【问题标题】:Scala Partial Function CompositionScala偏函数组合
【发布时间】:2018-07-13 17:57:12
【问题描述】:

我正在尝试组合这两个函数:

// 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)
                                ^

谁能解释为什么会出现这个错误,以及如何避免它?

【问题讨论】:

  • 试试... = Try.apply[DataMap](_)... = Try.apply(_: DataMap)
  • 酷,它现在似乎可以工作,但你能解释一下这个错误是如何产生的吗?
  • 嗯,我已经阅读了很多这样的答案,但我仍然没有完全理解它。我正在寻找解释为什么在我的代码中特别需要它。我的是一个具体的例子,所以这可能会帮助我理解更多。

标签: scala partial-application


【解决方案1】:

这是因为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-expansion,因为 DataMap => DataMap 类型归属强制编译器期望函数作为返回类型,因此 action(2) 会自动转换为 action(2)(_)

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

请注意,这是可行的:

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

但它不能很好地与compose 配合使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-28
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 2017-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多