美文网首页iOS开发之常用技术点
深入理解scala的柯里化( currying or curry

深入理解scala的柯里化( currying or curry

作者: onwingsofsong | 来源:发表于2018-09-24 10:00 被阅读72次

    百度百科定义:

    柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。

    从数学的角度讲,这是一个对函数消元求解的过程:

    def f(x:Int,y:Int)=x+y

    def g(x:Int)=f(x,1)

    def z=g(1)

    z=2

    那么z也可以写成这样:def z=(x:Int)=>(y:Int)=>x+y

    例如:

    def add(x:Int,y:Int)=x+y

    柯里化后:

    def add(x:Int)(y:Int)=x+y

    实际实现是scala的语法糖,依次调用两个普通函数,第一次调用函数(x),第二次调用时使用了(x)的返回值。

    def add=(x:Int)=>(y:Int)=>x+y

    那么具体怎么实现柯里化呢?

    假设我原始的普通函数 def add(x:Int,y:Int)=x+y

    目标函数是Int=>Int=>Int (或者Int=>(Int=>Int))

    大概长这样def add=(x:Int)=>(y:Int)=>x+y

    抽象出来是[参数1=>参数2=>function(参数1,参数2)]

    柯里化函数:

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

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

    用柯里化函数调用非柯里化函数add后:

    def add(x:Int,y:Int)=x+y

    def addCurry=curry(add)

    addCurry: Int => (Int => Int)

    测试:

    addCurry(1)(2)

    res10: Int = 3

    在scala的隐式转换中,currying经常被用到,以monoid为例:

    trait Monoid[A] {

         def mappend(a1: A, a2: A): A

          def mzero: A

         }

    object IntMonoid extends Monoid[Int] {

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

          def mzero: Int = 0

          }

    def sum[A](xs: List[A])(implicit m: Monoid[A]): A = xs.foldLeft(m.mzero)(m.mappend)

    implicit val intMonoid = IntMonoid

    sum(List(1, 2, 3, 4))

    另外通过currying可以更随意组装函数:

    def combine(a:Int)(b:(Int,Int)=>Int)=(x:Int)=>b(a,x)

    combine: (a: Int)(b: (Int, Int) => Int)Int => Int

    def add(x:Int,y:Int)=x+y

    def minus(x:Int,y:Int)=x-y

    结果如下:

    combine(1)(add)(1)

    res20: Int = 2

     combine(5)(minus)(2)

    res21: Int = 3

    已经知道curry,那么逆向函数uncurry呢?

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

    我们的目标是把A=>(B=>C)转为(A,B)=>C,即:

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

    测试一下:

    def add(x:Int,y:Int)=x+y

    curry(add)(1)(2)

    res1: Int = 3

    uncurry(curry(add))(1,2)

    res2: Int = 3

    ---------------------

    本文来自 onwingsofsong 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/onwingsofsong/article/details/77822920?utm_source=copy

    相关文章

      网友评论

        本文标题:深入理解scala的柯里化( currying or curry

        本文链接:https://www.haomeiwen.com/subject/wkucoftx.html