首页 > 解决方案 > 如何在 Scala 中使用类型参数定义隐式函数?

问题描述

我正在阅读动手 Scala 编程,但我被困在递归类型类推理上。

该部分解释了如何从多种数据类型编写解析器。它给出了下面的例子

trait StrParser[T]{ def parse(s: String): T }
object StrParser{
  implicit object ParseInt extends StrParser[Int]{
    def parse(s: String) = s.toInt
  }
  implicit object ParseBoolean extends StrParser[Boolean]{
    def parse(s: String) = s.toBoolean
  }
  implicit object ParseDouble extends StrParser[Double]{
    def parse(s: String) = s.toDouble
  }
}

上面的代码运行良好。之后,它继续进行递归类型类推断。它在下面显示了一个蕴涵函数。

implicit def ParseSeq[Int](implicit p: StrParser[Int]) = new StrParser[Seq[Int]]{
  def parse(s: String) = s.split(',').toSeq.map(p.parse)
}

但是,运行此代码后,我遇到了错误。我在 Ammonite、Scala 上尝试过并编译它,但一切都不起作用。

result type of implicit definition needs to be given explicit

我在谷歌上查找错误,只找到两个不相关的结果。我该如何解决这个问题?我错过了什么?

标签: scala

解决方案


这本书是为 Scala 2 编写的,它可以毫无错误地处理此代码

trait StrParser[T]{ def parse(s: String): T }
object StrParser{
  implicit object ParseInt extends StrParser[Int]{
    def parse(s: String) = s.toInt
  }
  implicit object ParseBoolean extends StrParser[Boolean]{
    def parse(s: String) = s.toBoolean
  }
  implicit object ParseDouble extends StrParser[Double]{
    def parse(s: String) = s.toDouble
  }
}

implicit def ParseSeq[T](implicit p: StrParser[T]) = new StrParser[Seq[T]]{
  def parse(s: String) = s.split(',').toSeq.map(p.parse)
}

def parseFromString[T](s: String)(implicit parser: StrParser[T]) = {
  parser.parse(s)
}

parseFromString[Seq[Int]]("1,1")

看来您正在使用 Scala 3,因此您需要将定义更改ParseSeq为:

implicit def ParseSeq[T](implicit p: StrParser[T]): StrParser[Seq[T]] = new StrParser[Seq[T]]{
  def parse(s: String) = s.split(',').toSeq.map(p.parse)
}

另请注意,本书将其定义ParseSeq为具有参数名称的泛型方法T,这比一种数学现有类型(即Int)更好的泛型参数名称:

implicit def ParseSeq[T](implicit p: StrParser[T]) = new StrParser[Seq[T]]{
  def parse(s: String) = s.split(',').toSeq.map(p.parse)
}

推荐阅读