【问题标题】:When is a scala partial function not a partial function?什么时候scala偏函数不是偏函数?
【发布时间】:2011-02-21 16:44:11
【问题描述】:

在创建 String 到部分函数的映射时,我遇到了意外行为。当我创建一个部分函数作为地图元素时,它工作正常。当我分配给一个 val 时,它会调用它。尝试调用检查会产生错误。这是预期的吗?我在做傻事吗?注释掉 check() 以查看调用。我正在使用 scala 2.7.7

def PartialFunctionProblem() = {
    def dream()() = {
        println("~Dream~");
        new Exception().printStackTrace()
    }
    val map = scala.collection.mutable.HashMap[String,()=>Unit]()
    map("dream") = dream()      // partial function
    map("dream")()              // invokes as expected
    val check = dream()         // unexpected invocation
    check()                     // error: check of type Unit does not take parameters 
}

【问题讨论】:

  • 感谢您的帮助。当我用 dream()_ 替换我的 dream() 调用时,它的行为符合我的预期。我会出去阅读更多关于 PartialFunctions 的内容,这样我就不会再误用这个词了。

标签: scala function functional-programming partial-application partialfunction


【解决方案1】:

为方便起见,Scala 允许您在调用方法时省略空括号,但它很聪明地看到第一种情况下的预期类型是()=>Unit,因此它不会为您删除所有括号;相反,它会为您将方法转换为函数。

然而,在val check 的情况下,它看起来就像一个函数调用结果被分配给一个变量。事实上,所有这三个都做完全相同的事情:

val check = dream
val check = dream()
val check = dream()()

如果您想将方法转换为函数,请将_ 放在方法之后代替参数列表。因此,

val check = dream() _

会做你想做的。

【讨论】:

    【解决方案2】:

    好吧,问题是你搞错了。 :-)

    以下是一些概念上的错误:

    def dream()() = {
        println("~Dream~");
        new Exception().printStackTrace()
    }
    

    这不是偏函数。这是一个带有两个空参数列表的 curried 方法,返回 Unit

    val map = scala.collection.mutable.HashMap[String,()=>Unit]()
    

    这个map中值的类型不是偏函数,而是函数。具体来说,Function0[Unit]。部分函数的类型为 PartialFunction[T, R]

    map("dream") = dream()      // partial function
    

    这里发生的事情是 Scala 部分应用的方法转换为函数。这不是一个简单的任务。 Scala 进行转换是因为类型推断器可以猜出正确的类型。

    val check = dream()         // unexpected invocation
    

    这里没有帮助类型推断器的预期类型。但是,可以省略空参数列表,因此这只是一个方法调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多