【问题标题】:How is this exactly a curried function?这究竟是一个柯里化函数?
【发布时间】:2014-12-18 12:27:26
【问题描述】:

我正在阅读 Scala 中的函数式编程,并进行了不同的练习。我遇到了咖喱。

有人可以向我解释一下这个 curried 函数以及它是如何工作的吗?我似乎可以理解这段代码。与我在不同博客上看到的关于 Scala 柯里化的文章相比。

def curry[A,B,C](f: (A, B) => C): A => (B => C) =  a => b => f(a,b)

是来自 a => b => f(a,b) 的 a 一个函数,如果是,它的参数是什么?

还更新是什么意思? a in a => b => f(a,b) 是什么意思?是一个函数,它会返回一个名为 b 的函数,它接受单个参数并返回一个函数?

【问题讨论】:

    标签: scala currying


    【解决方案1】:

    我假设你理解柯里化的概念并且类型定义对你来说是有意义的:A => B => C。

    实现是:a => b => f(a,b),你可以读成:

    ... = { a => 
            { b => 
              { f(a,b) }
            }
          }
    

    所以a 是作为A => (B => C) 类型函数的输入接受的参数。此函数返回第二个函数 - 类型为 B => C,它采用 b:B 并将 f 应用于两者。

    编辑:如果它可以帮助您理解,您可以使用这个非常详细的版本:

    def curry[A,B,C](f: (A, B) => C): A => (B => C) = {
    
      def aToBToC(a: A): B => C = {
    
        def bToC(b: B): C = {
          f(a,b)
        }
    
        bToC
      }
    
      aToBToC
    }
    

    看看我如何在嵌套范围内定义私有函数? (我没有在 REPL 中尝试过,可能有错字,但你明白了。)

    【讨论】:

    • 那么你说 A 是函数的参数是什么意思?
    • 那么你是说 'a' 是表达式 a => b => f(a,b) 中的一个函数?
    • 不,a 是A => (B => C 类型的匿名函数的第一个参数 - 它接受A 并将B 的函数返回到C。这就是柯里化的想法:不是同时使用A 和B 来生成C,而是使用一个接一个的参数。也许你很困惑,因为这个函数是匿名的并且没有名字。
    • 它返回了一个类型不匹配,我明白了,它是匿名函数但我认为 scala 无法推断参数类型?
    • 我在代码 sn-p 中修复了问题。 Scala 可以在这种情况下推断类型参数。
    【解决方案2】:

    你定义了一个函数curry,它接受另一个函数作为参数。该函数的返回类型是A => (B => C),也是一个从A到B => C的函数。

    之后你定义了一个A => (B => C)的实现,同样对于给定的a返回一个函数b => f(a,b)。

    示例:

    def plus(a: Int, b:Int): Int = a + b
    

    plus的咖喱版:

    scala> def plusC(a:Int): Int => Int = plus(a, _)
    plusC: (a: Int)Int => Int
    
    scala> plusC(1)
    res4: Int => Int = <function1>
    
    scala> res4(10)
    res5: Int = 11
    

    【讨论】:

    • 有点困惑,所以在声明中,'a => b => f(a,b)' 'a' 是一个函数?
    • 不,'a' 是返回函数的第一个参数。您可以将 'a => b => f(a,b)' 解读为:我的函数从 'a' 返回一个带有一个参数的函数,它返回一个带有一个参数的第二个函数 'b => f(a,b)'来自“b”的输入参数(参数“a”是固定的)。
    【解决方案3】:

    这不是一个柯里化函数。这是一个 curry 方法(注意:函数和方法在 Scala 中是非常不同的概念),即 执行 currying 的方法。它的返回值是一个柯里化函数;它接受一个有两个参数的函数并返回一个柯里化函数。

    【讨论】:

      【解决方案4】:

      def curry[A,B,C] 本身不是柯里化函数,它只是展示了如何将带有两个参数的函数f: (A, B) =&gt; C 转换为柯里化函数A =&gt; (B =&gt; C)。 a =&gt; b =&gt; f(a, b) 表示函数接受参数a 并返回函数b =&gt; f(a, b),而函数又返回最终值f(a, b)。

      【讨论】:

        猜你喜欢
        • 2019-03-26
        • 2013-06-03
        • 2016-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-07
        • 2012-10-06
        • 1970-01-01
        • 2020-08-18
        相关资源
        最近更新 更多