List.orElse的Scala意外输出

Wei*_*Lin 1 scala implicit-conversion

我希望以下代码输出Seq(0),而不是它返回一个函数?

@ Seq(0).orElse(Seq(1))
res2: PartialFunction[Int, Int] = <function1>
Run Code Online (Sandbox Code Playgroud)

我一开始怀疑通过语法将其添加orElseapply函数上,但是从那时起它没有尝试:

@ Seq(0).apply.orElse(Seq(1))
cmd3.sc:1: missing argument list for method apply in trait SeqLike
....(omit)
Run Code Online (Sandbox Code Playgroud)

我在IntellJ检查过没有implicit conversion.
怎么了?


编辑:我希望是:
Seq.empty.orElse(Seq(1)) == Seq(1)
Seq(0).orElse(Seq(1)) == Seq(0)


谢谢@AndreyTyukin回答.
在一行中,orElse具有不同类型的不同语义,现在不Seq继承,行为也是如此.PartialFunctionOptionorElse

And*_*kin 5

Seq(0)其视为PartialFunction仅在索引处定义的值0,并且0如果给定唯一有效的输入,则生成常量值0.

当你调用orElseSeq(1),会构造一个新的部分函数,​​它首先尝试应用Seq(0),如果它在定义的域中没有找到任何内容Seq(0),则它会回退到Seq(1).由于域Seq(1)的域名Seq(0)(即只是{0}),orElse在这种情况下基本上没有任何作用,并返回相当于的部分函数Seq(0).

因此,结果再次定义了一个部分函数,0它给出了0它是否传递了唯一有效的输入0.


这是一个具有不同长度序列的非简并示例,希望能够更容易理解该orElse方法的用途:

val f = Seq(1,2,3).orElse(Seq(10, 20, 30, 40, 50))
Run Code Online (Sandbox Code Playgroud)

是部分功能:

f: PartialFunction[Int,Int] = <function1>
Run Code Online (Sandbox Code Playgroud)

以下是将值0映射到4的方式:

0 to 4 map f

// Output: Vector(1, 2, 3, 40, 50)
Run Code Online (Sandbox Code Playgroud)

也就是说,它使用来自第一个序列的前三个值,然后回退到传递给orElse输入3和的第二个序列4.


这也适用于任意部分函数,​​而不仅仅是序列:

scala> val g = Seq(42,43,44).orElse[Int, Int]{ case n => n * n }
g: PartialFunction[Int,Int] = <function1>

scala> 0 to 10 map g
res7 = Vector(42, 43, 44, 9, 16, 25, 36, 49, 64, 81, 100)
Run Code Online (Sandbox Code Playgroud)

如果要在两个序列之间进行选择而不将它们视为部分函数,​​则可以考虑使用

Option(Seq(0)).getOrElse(Seq(1))
Run Code Online (Sandbox Code Playgroud)

Seq(0)如果这是您想要的,这将返回.