2016-08-18 106 views
0

第一个stackoverflow问题和新的斯卡拉。想了解多态类型与这个例子中,我写道:Scala类型不匹配:Nothing => Nothing?

def identFun[A](a: A): A = a 

def testerChar(l: List[Char], f: Char => Char): List[Char] = { 
    val li = l.map((r: Char) => f(r: Char)) 
    li 
} 

工作正常(如果不是有点冗长):

scala> testerChar(List('a','b','c'), identFun) 
res49: List[Char] = List(a, b, c) 

但是:

def testerA[A](l: List[A], f: A => A): List[A] = { 
    val li = l.map((r: A) => f(r: A)) 
    li 
} 

产量:

scala> testerA(List('a','b','c'), identFun) 
<console>:14: error: type mismatch; 
found : Nothing => Nothing 
required: Char => Char 
     testerA(List('a','b','c'), identFun) 

我在想什么t将允许“testerA”返回传递给它的任何类型的身份?

谢谢!

尝试:

def testerA[A](l: List[A])(f: A => A): List[A] = { 
    val li = l.map((r: A) => f(r: A)) 
    li 
} 

了:

scala> testerA(List('a','b','c'), identFun) 
<console>:14: error: too many arguments for method testerA: (l: List[A])(f: A => A)List[A] 
    testerA(List('a','b','c'), identFun) 
+0

将其更改为'def testerA [A](l:List [A])(f:A => A)' –

+0

或者传递类型。 testerA [Char](List('a','b','c'),identFun) – sascha10000

+0

curried'def'应该像这样调用:'testerA(List(...))(identFun)',使用''(''代替'',''' – Clashsoft

回答

1

事实证明,如果你简化了事情,你也可以得到你想要的。

scala> def identFun[A](a: A): A = a 
identFun: [A](a: A)A 

scala> def testerA[A](l: List[A])(f: A => A): List[A] = l.map(f) 
testerA: [A](l: List[A])(f: A => A)List[A] 

scala> testerA(List('a','b','c'))(identFun) 
res5: List[Char] = List(a, b, c) 
0

对于我来说,称这是像这样的工作:

testerA(List('a','b','c'), identFun[Char]) 

我怀疑testerA的是A型是不同的类型identFun的类型A.我不知道你将如何导致它自动解析为字符。

+0

更新,这也适用:testerA [Char](List('a','b','c'),identFun) –

1

其他答案解释了如何解决问题,但不是问题本身。问题是,如果在不指定类型参数的情况下编写testerA(List('a','b','c'), identFun),则Scala不能使用第一个参数来推断A,然后使用A来确定第二个参数的类型。

相反,它首先检查两个参数。同样,它需要推断List.applyidentFun的类型参数。在第一种情况下,它选择Char(当然),但在第二种情况下它选择Nothing。在此之后,它试图最终决定A,但当然参数现在不兼容。

使用def testerA[A](l: List[A])(f: A => A),A推断使用第一个参数,然后用于检测f

+0

谢谢@AlexeyRomanov的解释。我从Haskell的经历中得出了同样的结论。谢谢大家的帮助! – ericky