【问题标题】:Is it possible to accept arbitrary extractor as method argument是否可以接受任意提取器作为方法参数
【发布时间】:2016-12-30 07:36:40
【问题描述】:

我想重用现有的提取器并组合它们。 A => Option[B]B => Option[C] 完美匹配。

但我很困惑,我怎么能在代码中表达这种关系。

明显的方法不可用是有充分理由的:

type Extractor[F,T] = {
  def unapply(from : F) : Option[T]
}

def bind[A,B,C](l : Extractor[A,B], r : Extractor[B,C]) = new {
  def unapply(from : A) : Option[C] = l.unapply(from).flatMap(r.unapply _)
}

scalac 回复:

Extractors.scala:7: error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
    def unapply(from : A) : Option[C] = l.unapply(from).flatMap(r.unapply _)
                ^
Extractors.scala:3: error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
    def unapply(from : F) : Option[T]
                ^
two errors found

Internet 表示这是由于类型擦除导致的预期行为。

是否可以改写代码以使其正常工作?

【问题讨论】:

    标签: scala type-parameter extractor structural-typing


    【解决方案1】:

    结构细化中的参数类型可能不引用在该细化之外定义的抽象类型`

    正如错误提示,structure type 不能引用外部定义的generic type

    对于您的示例,您可以使用 trait 执行相同的操作,例如:

    trait Extractor[F, T] {
      def unapply(from: F): Option[T]
    }
    
    def bind[A, B, C](l: Extractor[A, B], r: Extractor[B, C]) = new Extractor[A, C] {
      override def unapply(from: A): Option[C] = l.unapply(from).flatMap(r.unapply)
    }
    

    【讨论】:

    • 我如何将正则表达式提取器匹配到新定义的类型Extractor
    • @ayvango 你能粘贴你的正则表达式提取器吗?
    • val date = """(\d\d\d\d)-(\d\d)-(\d\d)""".r 还有很多其他预定义的提取器。我想重复使用它们。
    • 也许您可以使用自己的提取器包装自定义 Extractor,例如:new Extractor[String, List[String]] { override def unapply(from: String): Option[List[String]] = date.unapplySeq(from) }
    • 问题是关于使用任意提取器的方法。可能通过隐式转换或其他方式。语言设计对提取器基础设施的使用提出了相当大的挑战
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    • 2012-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多