斯卡拉列表错误

问题描述:

经过大量的Java和一些Haskell,我想看看Scala。从下面的代码中,我得到这个错误信息斯卡拉列表错误

type mismatch; found : List[Nothing] => Option[Nothing] required: List[Int] => Option[Nothing]

我不知道我做错了什么:

object MyFirstScalaObject { 

    def main(args: Array[String]) { 
     lazy val testValues:List[List[Int]] = List((1 to 10).toList, null, List()); 

     println( testFunction(last, testValues)); 
    } 

    def testFunction[I, O](f : I => O, inputs : List[I]): 
     List[(I, O)] = 
    inputs.zip(inputs.map(f)); 

    def last[A](xs:List[A]):Option[A] = xs match { 
    case x::Nil => Some(x); 
    case _::xs => last(xs); 
    case _ => None; 
    } 

} 

感谢您的任何意见。

干杯,

+2

你可以将'testFunction'定义为'testFunction [I,O](inputs:List [I])(f:I => O)',并将其用作'testFunction(testValues)(last)'。 – senia

+0

senia,我认为你应该把它变成一个答案,而OP应该让IMHO接受它。 – Blaisorblade

+0

@Blaisorblade:我已经发布它作为答案。但它是“如何”,而不是“为什么”。 – senia

,因为类型推断Scala中的工作方式,这是无法确定是什么类型参数last不得,所以它采取过于保守的后备猜想,这是Nothing

testFunction[List[Int],Option[Int](last, testValues) 

,或者你可以更充分地记录在testFunction声明的类型参数之间的关系,这将给型inferencer信息:

,当你调用testFunction您可以显式指定类型

def testFunction[A, I[_], O[_]](f : I[A] => O[A], inputs : List[I[A]]): List[(I[A], O[A])] 

明确地说,I和O是类型构造函数(kind * - > *),现在f的输入/输出类型更具体,推理器可以正确推断出A的参数t他最后的功能必须是Int。

+0

谢谢炖!我想我明白了。 (编辑)我知道了,但我的scala ide不... – markusw

+0

函数调用类型,也没有功能定义typecontructing类型。错误信息是:知道它需要“List [Int] => Option [Int]”,并假定只有“List [Nothing] => Option [Nothing]”。它可能是textValues-List中包含“null”值的一种压缩? – markusw

+0

user1905015:空值不是问题;它们不会影响testValues的类型推断,反正类型推断也不会发生,因为无论如何您都指定了完整类型。 炖:类型推断不及时推断A. – Blaisorblade

一个全面修订&测试版,采用塞尼亚的想法:

object MyFirstScalaObject { 
    def main(args: Array[String]) { 
     lazy val testValues = List((1 to 10).toList, null, List()) 
     println(testFunction(testValues)(last)) 
    } 

    def testFunction[I, O](inputs: List[I])(f: I => O): List[(I, O)] = 
    inputs.zip(inputs.map(f)) 

    def last[A](xs: List[A]): Option[A] = xs match { 
    case x :: Nil => Some(x) 
    case _ :: xs => last(xs) 
    case _ => None 
    } 
} 

类型推断进行左到右;来自一个参数列表的信息在下一个参数列表中使用。 在此代码,当调用testFunction Scala中可从第一参数推断I,那么它可以喂I作为函数f找出它的类型的输入类型(即,该参数last施加A = Int),那么它最终从函数的返回类型获得O的值。

我不能告诉你为什么在scala中的类型推断这样工作。

但有common way来帮助编译器在这种情况下 - parameter sections

def testFunction[I, O](inputs : List[I])(f: I => O): List[(I, O)] = inputs.zip(inputs.map(f)) 

用法:

testFunction(testValues)(last) 

类似的解决方案是添加方法testFunctionList类:

class LastsHelper[T](inputs: List[T]) { 
    def testFunction[O](f: T => O): List[(T, O)] = inputs.zip(inputs.map(f)) 
} 
implicit def toLastsHelper[T](inputs: List[T]) = new LastsHelper(inputs) 

您可以使用这些方法像List方法:

testValues.testFunction(last)