scala案例学习之Currying柯里化

【写在前面】
     由于之前工作的一些特殊情况,加上在比较多使用知识管理软件(为知/有道云笔记等)后,就越来越少写博客,但在生活工作却总感觉缺少了点东西,蓦然回首发现原来是“丢失了”"学习写作"的修炼心。故有必要重新治理一下博客,以rscala.com记录、分享自己在IT技术自我修炼与窥探历程。

一、初识Currying柯里化
  柯里化(Currying)技术 Christopher Strachey 以逻辑学家 Haskell Curry 命名的(尽管它是 Moses Schnfinkel 和 Gottlob Frege 发明的)。它是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。

  简单理解就是改变函数的表达形式 但其功能特性不变,这对于第一次接触 柯里化的人来讲,这样的一个技术貌似有点“鸡肋”,但如果你有丰富的JS编程经验的话,相信就一定会感受到 柯里化其实是具有很高的实用性的 。无论是在提高 适用性还是在延迟执行或者 固定易变因素等方面, 柯里化技术都发挥着重要的作用。

二、从案例角度学习scala柯里化
   还是老观点——无论是修炼新技术还是旧理论,结合小案例理解学习,才是最有效的方法。下面将通过几个例子来学习 scala柯里化。
    2.1、从2个整数相乘运算的函数来揭开 柯里化的神秘面纱
    在scala中定义 2个整数相乘运算的函数是非常简单的,具体如下:
    def  multiplie2par(x:Int,y:Int)=x*y
    使用 柯里化技术可以将上述2个整数的乘法函数改修为接受一个参数的函数,只是该函数返回是一个以原有第二个参数为参数的函数。
    def  multiplie1par(x:Int)=(y:Int)=>x*y
【ps说明: multiplie1par(x:Int)为接收一个参数的新等价函数, (y:Int)=>x*y则是新等价函数的返回体,它本身就是一个函数(严格来说应该是一个匿名函数),参数为除等价新函数的参数外原函数剩余的参数。
    上述 使用 柯里化技术得到等价新函数,在scala语言中看起来还不是很简洁,在scala中可以进一步简化为:
      def  multiplie1par1(x:Int)(y:Int)=x*y
     编译运行的结果如下:
    
同样对于三个整数乘法的函数在scala中由于有 柯里化的存在,自然有多种功能等价的函数定义形式,如以下四种函数都是实现了 三个整数乘法功能,只不过调用不同形式参数过程略有不同,直接参入三个参数的一步到位就可以得到运算结果,而传入1或者2个参数的需要分步骤再传入第2/3或者第3个参数才能求出三个整数相乘的结果,很好地体现了 延迟执行或者 固定易变因素等方面能力
     def  multiplie3par(x:Int,y:Int,z:Int)=x*y*z
     def  multiplie3par1(x:Int)=( y:Int,z:Int )=>x*y*z
     def  multiplie3par2(x:Int)( y:Int )(z :Int )=x*y*z
     def  multiplie3par3(x:Int)( y:Int )=(z :Int )=>x*y*z
编译执行的结果都是一样

     2.2、scala中柯里化的另一种典型案例——correspondsf方法的柯里化应用
    在scala中 corresponds方法能使得两个序列按照一定的条件进行比较,该方法其实也是经过 柯里化参数的。在scala的API中该方法定义如下:在 方法签名描述中有两个参数,that序列和p函数,其中p函数有两个参数,第二个参数类型是与that序列一致的。应用 柯里化,我们可以省去第二个参数中B的类型,因为从that序列中推断出B的类型。
     def corresponds[B](that: GenSeq[B])(p: (T, B) ⇒ Boolean): Boolean
     因此假如有字符串类型序列a和字符串序列b,我们可以使用a.  corresponds(b)(_.  equalsIgnoreCase(_) )来判断两个字符串序列在不区分大小的情况是否一致,这就为编程带来了“魔法般”的灵活性。    

三、总结柯里化的作用

   3.1、 柯里化技术 在提高 适用性还是在延迟执行或者 固定易变因素等方面有着重要 重要的作用,加上scala语言本身就是推崇简洁编码,使得同样功能的函数在定义与转换的时候会更加灵活多样。 另外在Spark的源码中有大量运用scala 柯里化技术的情况,需要掌握好该技术才能看得懂相关的源代码。
  3.2、在scala 柯里化中,闭包也发挥着重要的作用。所谓的闭包就是变量出了函数的定义域外在其他代码块还能其作用,这样的情况称之为闭包。就上述讨论的案例而言,如果没有闭包作用,那么转换后函数其实返回的匿名函数是无法在与第一个参数x相关结合的,自然也就无法保证其所实现的功能是跟原来一致的。

本文出自AiTi修炼|大技术窥探 ,转载时请注明出处与连接。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值