奇怪的scala错误。找到:scala.Double需要Double

时间:2018-12-02 14:55:14

标签: scala functional-programming tree

我有一棵树,用于在节点中存储元素列表。 我需要编写一个接受这种树并返回在节点中具有元素总数的树的函数。

我认为这是一个简单的任务,但是发生了一些错误: 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)

我不知道为什么要在那里期待字符串,所以请向我解释一下:)

2 个答案:

答案 0 :(得分:5)

  1. 类名应以大写字母开头。
  2. 0是32位整数,您希望0d用于64位Double
  3. 您要为transformTree定义Double,而不是为绑定到名为Double的类型变量的任意类型定义。当前,您的函数签名等效于def transformTree[X](t: Tree[List[X]]): Tree[X],并且对X几乎一无所知,只不过它是Any的子类型,因此具有+运算符来连接其带有其他字符串的字符串表示形式。
  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)

答案 1 :(得分:3)

好吧...问题是当您定义如下的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开头的fold 0,因此这意味着您的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)