斯卡拉列表错误
经过大量的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;
}
}
感谢您的任何意见。
干杯,
,因为类型推断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。
谢谢炖!我想我明白了。 (编辑)我知道了,但我的scala ide不... – markusw
函数调用类型,也没有功能定义typecontructing类型。错误信息是:知道它需要“List [Int] => Option [Int]”,并假定只有“List [Nothing] => Option [Nothing]”。它可能是textValues-List中包含“null”值的一种压缩? – markusw
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)
类似的解决方案是添加方法testFunction
到List
类:
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)
你可以将'testFunction'定义为'testFunction [I,O](inputs:List [I])(f:I => O)',并将其用作'testFunction(testValues)(last)'。 – senia
senia,我认为你应该把它变成一个答案,而OP应该让IMHO接受它。 – Blaisorblade
@Blaisorblade:我已经发布它作为答案。但它是“如何”,而不是“为什么”。 – senia