【问题标题】:Convincing scala compiler that Nil has the right type [duplicate]令人信服的 scala 编译器 Nil 具有正确的类型 [重复]
【发布时间】:2014-11-26 01:32:21
【问题描述】:

所以我在 scala 中得到了我的 List 类版本:

sealed trait List[+A] {
  (...)
}

case object Nil extends List[Nothing] 
case class Cons[+A](_head: A, _tail: List[A]) extends List[A]

现在我正在尝试用我的foldLeft 来写reverse,如下所示:

@annotation.tailrec
def foldLeft[A,B](l: List[A], z: B)(f: (B, A) => B): B = l match {
        case Nil => z
        case Cons(x,xs) => foldLeft(xs,f(z,x))(f)
}

这是有问题的部分:

def revers[A](l:List[A]) : List[A] = foldLeft(l,Nil)((b,a) => Cons(a,b))

这给了我类型错误:

[error]  found   : datastructures.Cons[A]
[error]  required: datastructures.Nil.type
[error]         foldLeft(l,Nil)((b,a) => Cons(a,b))

我可以通过完全不使用 Nil 来解决这个问题:

def revers[A](l:List[A]) : List[A] = l match {
            case Nil => Nil
            case Cons(x,xs) => foldLeft(xs,Cons(x,Nil))((b,a) => Cons(a,b))
}

但我还是想知道如何通过这个?

【问题讨论】:

    标签: scala types functional-programming


    【解决方案1】:

    你可以指定类型:

    scala> def revers[A](l:List[A]) : List[A] = 
                   foldLeft(l,Nil:List[A])((b,a) => Cons(a,b))
    revers: [A](l: List[A])List[A]
    
    scala> val l:List[Int] = Cons(1,Cons(2,Cons(3,Nil)))
    l: List[Int] = Cons(1,Cons(2,Cons(3,Nil)))
    
    scala> revers(l)
    res0: List[Int] = Cons(3,Cons(2,Cons(1,Nil)))
    

    Scala 的类型推断一次只工作一个块,因此当您编写 foldLeft(l,Nil) 时,它期望返回类型为 Nil。您传递的函数 ((b,a) => Cons(a,b))) 的返回类型为 Cons[A],导致错误。在 foldLeft(l, Nil) 中指定 Nil:List[A] 会阻止它。请参阅 stackoverflow.com/questions/9785655/... 以获得更好的解释。

    【讨论】:

    • 感谢您的回答。你能解释一下,为什么编译器会抱怨吗?由于 Nil 是 List[Nothing] 的扩展,其中 List 具有协变类型构造函数,我认为一切都应该开箱即用?如果我记得 Nothing 是 scala 中所有内容的子类型,那么特别是任何将被替换的“A”?
    • Scala 的类型推断一次只工作一个块,因此当您编写foldLeft(l,Nil) 时,它期望返回类型为Nil。您传递的函数 ((b,a) => Cons(a,b))) 的返回类型为 Cons[A],从而导致错误。在foldLeft(l, Nil) 中指定Nil:List[A] 会阻止它。请参阅stackoverflow.com/questions/9785655/… 以获得更好的解释。
    • 再次感谢您回答并指出我正确的方向。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-10
    • 2018-10-27
    • 1970-01-01
    • 2019-08-31
    • 2017-02-25
    • 2011-12-04
    • 1970-01-01
    相关资源
    最近更新 更多