【问题标题】:Weird scala errors. found: scala.Double required Double奇怪的 scala 错误。找到:scala.Double 需要 Double
【发布时间】:2018-12-03 00:24:05
【问题描述】:

我有一个存储节点中元素列表的树。 我需要编写一个函数来接受这样的树并返回在节点中有元素总和的树。

我认为这是一项简单的任务,但出现了一些错误: errors

这是 IntelliJ 显示的内容:

code with compiler error

最后是我的代码:

sealed trait tree[+A]
case object Empty extends tree[Nothing]
case class Node[A](element:A,left:tree[A],right:tree[A]) extends tree[A]

val tr=Node(List(1,2,3),Node(List(3,4,5),Empty,Node(List(2,4,5),Empty,Empty)),Node(List(6,7,8),Empty,Empty))

def transformTree[Double](t:tree[List[Double]]):tree[Double]={
t match{
case Empty => Empty
case Node(l,left,right)=>Node[Double](l.foldLeft(0)((a:Double,b:Double)=>(a+b)),transformTree(left),transformTree(right))
}
}
   transformTree(tr)

我不知道为什么它在那里期待字符串,所以如果可以的话,请向我解释一下:)

【问题讨论】:

    标签: scala functional-programming tree


    【解决方案1】:
    1. 类名应以大写开头。
    2. 0 是一个 32 位整数,您需要 0d 为 64 位 Doubles。
    3. 您想为Double 定义transformTree,而不是为绑定到名为Double 的类型变量的任意类型。目前,您的函数签名等同于def transformTree[X](t: Tree[List[X]]): Tree[X],除了XAny 的子类型之外,几乎一无所知,因此有一个+ 操作用于将其字符串表示与其他字符串连接起来。李>
    4. 您的tr 应该是Tree[Double],而不是Tree[Int]
    5. sum,什么都不需要fold。即使你想foldLeft,也应该是l.foldLeft(0d)(_ + _)

    这样编译:

    sealed trait Tree[+A]
    case object Empty extends Tree[Nothing]
    case class Node[A](element:A,left:Tree[A],right:Tree[A]) extends Tree[A]
    
    val tr = Node(List(1d,2d,3d),Node(List(3d,4d,5d),Empty,Node(List(2d,4d,5d),Empty,Empty)),Node(List(6d,7d,8d),Empty,Empty))
    
    def transformTree(t: Tree[List[Double]]): Tree[Double] = {
      t match{
        case Empty => Empty
        case Node(l, left, right) => 
          Node[Double](l.sum, transformTree(left), transformTree(right))
      }
    }
    transformTree(tr)
    

    【讨论】:

      【解决方案2】:

      嗯...问题是当您定义 def 时,如下所示,

      def abc[A](a: A) = ??
      

      这里的A 是一个泛型类型参数,这个类型参数Adef 范围内的类型解析中具有最高优先级。因此,任何其他类型的A 在此范围内都不会被识别为A

      简单来说,如果你做类似的事情

      def abc[Double](a: Double) = a
      

      这里的Double 不是你知道的实际的Double,而是一个类型参数,对def 的用户开放。

      而上面的行等价于,

      def abc[A](a: A) = a
      // Or
      def abc[B](b: B) = b
      

      这意味着在您的def transformTree[Double]def 的范围内,这些Double 不是实际的Double,而是一个变量类型,将在实际使用函数时确定。

      而且由于您使用的 a + b fold0 开头,这意味着您的 transform 几乎是固定类型的。如果你想为Double实现它,

      sealed trait Tree[+A]
      case object Empty extends Tree[Nothing]
      case class Node[A](element: A, left: Tree[A], right: Tree[A]) extends Tree[A]
      
      val tr = Node(
        List(1d, 2d, 3d),
        Node(
          List(3d, 4d, 5d),
          Empty,
          Node(
            List(2d, 4d, 5d),
            Empty,
            Empty
          )
        ),
        Node(
          List(6d, 7d, 8d),
          Empty,
          Empty
        )
      )
      
      def transformTree(t: Tree[List[Double]]): Tree[Double] = {
        t match {
          case Empty => Empty
          case Node(l, left, right) => Node(
            l.foldLeft(0d)((acc: Double, elem: Double) => (acc + elem)),
            transformTree(left),
            transformTree(right)
          )
        }
      }
      
      transformTree(tr)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多