2

我正在编写函数文字,尽管与大多数例子不同,我已经看到我以一个多参数函数开始,然后curried。构成函数文字时通过下划线的Scala部分应用

我:

//types 
case class Thing1(v: Double) 
case class Thing2(v: Double) 
case class Thing3(v: Double) 
type Multiplier = Double 

//functions 
val f1 = (t: Thing1, m: Multiplier) => Thing2(m * t.v) 
val f2 = (t: Thing2) => Thing3(t.v) 

我要撰写F1和F2得到一个组合功能

Thing1 => (Multiplier => Thing3) 

正如预期的那样,以下不会编译:

val fcomposed1 = f1.curried.andThen(f2) // does not compile 

通过实验,我能够确定下列内容可以编译并且具有合适的签名:

val fcomposed2 = f1.curried(_:Thing1).andThen(f2) 

我读过的各种来源,如What are all the uses of an underscore in Scala?和可能相关的Why does Scala apply thunks automatically, sometimes?但不幸的是我现在还不能制定出精确地一步一步这里发生了什么,以及为什么它的工作原理。

而且,我预计分为两个表达式以上,以相同方式工作,以fcomposed2,但不是第二不编译:

val f1partial = f1.curried(_:Thing1) 
val fcomposed3 = f1partial.andThen(f2) // does not compile - same error as fcomposed1 

貌似f1partial返回相同的签名f1.curried,这使得我还想知道更早的失败的作品。

有人能请一步一步解释两种行为吗?

回答

3

在这里,_充当lambda表达式的语法糖,但在您可能不期望的级别。

f1.curried具有类型Thing1 => Multiplier => Thing2

f1.curried(_:Thing1)相同{ x: Thing1 => f1.curried(x) }。由于f1.curried(x)的结果为Multiplier => Thing2,因此整个表达式的最终类型仍为Thing1 => Multiplier => Thing2。因此,对结果(f1partial)调用andThen(f2)是无效的,因为函数f2(Thing2)的输入类型与前一个函数(Multiplier => Thing2)的输出不同。

相比之下,f1.curried(_:Thing1).andThen(f2)扩展为{ x: Thing1 => f1.curried(x).andThen(f2) }f1.curried(x)评估为类型Multiplier => Thing2,如前所述,所以你可以就这样,致电Multiplier => Thing3andThen(f2)。所以,那么整个表达式的计算结果为Thing1 => Multiplier => Thing3

也许它更清楚,如果你认为这两个词语之间的区别:

val fcomposed1 = { x: Thing1 => f1.curried(x).andThen(f2) } // valid 
val fcomposed2 = { x: Thing1 => f1.curried(x) }.andThen(f2) // error 
+0

谢谢,这看起来像答案虽然我将不得不读再多几次才能真正掌握它! PS:在第二段中,'扩展到'之后的代码块有一个缺失的大括号。 – theStrawMan

+0

答案显示了表达式如何扩展,最后两行清楚地解释了最终的区别,非常感谢。 虽然Scala_does_以不同的方式扩展了两个表达式(fcomposed2和fcomposed3,引用我的问题),但我仍然发现它有点奇怪 - 这是我可能需要更多阅读/思考才能理解的东西。 – theStrawMan

+0

额外的注意事项:一旦我理解这里发生了什么与下划线lambda表达式(毕竟不是部分应用),我发现[this](https://stackoverflow.com/questions/7673545/usage-of-in-scala-lambda功能)和[this](https://stackoverflow.com/questions/4422016/scala-underscore-minimal-function)值得一读的问题。 – theStrawMan