Scala部分函数组成

时间:2018-07-13 17:57:12

标签: scala partial-application

我正在尝试组合这两个功能:

// some case class that just holds data
case class DataMap( ... )

val action(i: Int)(data: DataMap): DataMap = { ... }

val tryFunction: DataMap => Try[DataMap] = Try.apply[DataMap]
val actionFunction: DataMap => DataMap = action(2)

tryFunction compose actionFunction

然后我得到这些错误:

Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `apply _` or `apply(_)` instead of `apply`.
     val tryFunction = Try.apply[DataMap]
                                ^


Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `action _` or `action(_)` instead of `action`.
     val actionFunction = action(1)
                                ^

有人可以解释为什么会出现此错误,以及如何避免该错误吗?

1 个答案:

答案 0 :(得分:2)

这是因为Try.apply的别名参数。这在这里有效:

import util.Try

case class DataMap()

def action(i: Int)(data: DataMap): DataMap = ???

val tryFunction: DataMap => Try[DataMap] = Try.apply[DataMap](_)
val actionFunction: DataMap => DataMap = action(2)

tryFunction compose actionFunction

action(2)不需要eta扩展,因为DataMap => DataMap类型的说明会强制编译器将函数视为返回类型,因此action(2)被转换为{{1} }。

action(2)(_)必须进行显式eta转换,因为Try.apply[DataMap]的输入类型是apply[A](按名称),而不仅仅是=> A。这就是为什么编译器拒绝自动对方法A进行eta扩展:类型不完全匹配的原因。如果显式地对其进行eta转换,则它等效于apply,因此输入类型为(d: DataMap) => Try.apply[DataMap](d),而不是DataMap

请注意,这样做会有效:

=> DataMap

但是它不能与val tryFunction: (=> DataMap) => Try[DataMap] = Try.apply[DataMap] 配合使用。