这是在课程功能编程课程中交叉发布的,因为该论坛的活动少得多。
我写了下面的代码(部分被编辑,因为它是作业):
type Occurrences = List[(Char, Int)]
def subtract(x: Occurrences, y: Occurrences): Occurrences = {
val mx: Map[Char, Int] = x toMap
y.foldLeft (redacted) (redacted => simple expression using updated and -)) toList
}
这会产生以下编译错误:
type mismatch; found : Map[Char,Int] required: <:<[(Char, Int), (?, ?)]
但是,如果我通过val语句添加第三行的副本(没有toList),则错误就会消失:
type Occurrences = List[(Char, Int)]
def subtract(x: Occurrences, y: Occurrences): Occurrences = {
val mx: Map[Char, Int] = x toMap
val foo: Map[Char, Int] = y.foldLeft (redacted) (redacted => simple expression using updated and -))
y.foldLeft (redacted) (redacted => simple expression using updated and -)) toList
}
我猜这与给类型检查器提供某种额外提示有关,但有没有人知道为什么会发生这种情况?
答案 0 :(得分:3)
下面是一些例子和一些解释为什么会发生。
首先,工作和非工作案例:
scala> { List('a -> 1, 'b -> 2).toMap
| println("aaa") }
aaa
scala> { List('a -> 1, 'b -> 2) toMap
| println("aaa") }
<console>:9: error: type mismatch;
found : Unit
required: <:<[(Symbol, Int),(?, ?)]
println("aaa") }
^
这是因为语法“obj method arg”被认为是“obj.method(arg)”,因此是“obj method \ n arg”,这样参数可以写在下一行。请注意以下内容:
scala> { val x = List('a -> 1, 'b -> 2) map
| identity
|
| println(x) }
List(('a,1), ('b,2))
与List('a -> 1, 'b -> 2).map(identity)
相同。
现在发现奇怪的错误消息found : Unit, required: <:<[(Symbol, Int),(?, ?)]
。碰巧toMap
实际上需要一个参数,这是它的签名:
def toMap[T, U](implicit ev: <:<[A,(T, U)]): Map[T,U]
,
但它是一个隐式参数,因此在这种情况下不需要明确提供。但是当你使用obj method \n arg
语法时,它会填充方法参数。在上面的非工作示例中,参数是println
,其类型为Unit
,因此编译器不接受它。
一种解决方法是让两个\n
分隔这些行:
scala> { List('a -> 1, 'b -> 2) toMap
|
| println("aaa") }
aaa
您还可以使用;
分隔线条。
答案 1 :(得分:2)
@RexKerr&amp; @DidierDupont是对的,你遇到了问题,因为你像二进制运算符一样调用toMap
,所以编译器吓坏了。
我的两分钱:您应该阅读Suffix Notation section of the Scala Style Guide。