偏函数应用指的是固化函数的一个或一些参数,从而产生一个新的函数。比如我们有一个记录日志的函数:

   1:  def log(level, message):
   2:      print level + ": " + message
   3:   
   4:  #usage
   5:  log("Warning", "this is one warning message")
   6:  log("Error", "this is one error message")

在这个函数基础上我们可以固化level参数,产生新的具有特定意义的log函数:

   1:  def logWarning(message):
   2:      log("Warning", message)
   3:   
   4:  def logError(message):
   5:      log("Error", message)
   6:   
   7:  #usage
   8:  logWarning("this is one warning message")
   9:  logError("this is one error message")

这就叫偏函数应用。

在Python中可以借助functools模块来完成偏函数应用,而不用手工编写代码。

   1:  from functools import partial
   2:   
   3:  logWarning = partial(log, "Warning")
   4:   
   5:  #usage
   6:  logWarning("this is one warning message")

partial是一个高阶函数(参数含有函数类型,返回值也是函数类型),所以对于3个或更多参数的函数我们还可以这样用:

   1:  def log(level, message, stack):
   2:      print level + ": " + message
   3:      print stack
   4:   
   5:  logUnknownError = partial(partial(log, "Error"), "Unknown")
   6:  logUnkownError("stack content")
   7:   
   8:  #output
   9:  #Error: Unkown
  10:  #stack content

Currying指的是将一个具有多个参数的函数,转换成能够通过一系列的函数链式调用,其中每一个函数都只有一个参数。我们对log函数进行Currying:

   1:  def log(level):
   2:      def logMessage(message):
   3:          print level + ": " + message
   4:   
   5:      return logMessage
   6:   
   7:  #usage
   8:  log("Warning")("this is one warning message")
   9:   
  10:  #or like this
  11:  logError = log("Error")
  12:  logError("this is one error message")
对于curried函数是不能使用多参数的调用方式:
log(“warning”, “this is one warning message”)
这样会得到错误,因为log只接受一个参数。
偏函数和Currying看起来有点类似,区别是什么呢?偏函数是用特定的值来具体化参数,而Currying是变成了一条函数链。
   1:  from functools import partial
   2:   
   3:  def log(level, message, stack):  
   4:        print level + ": " + message
   5:        print stack   
   6:        
   7:  #partial application
   8:  partialLogWarning = partial(log, "Warning")
   9:   
  10:  #currying
  11:  def curriedLog(level):
  12:      def logMsg(message):
  13:            def logStack(stack): 
  14:                print level + ": " + message
  15:                print stack
  16:   
  17:            return logStack
  18:   
  19:      return logMsg
  20:      
  21:  curriedLogWarning = curriedLog("Warning")
  22:   
  23:  #1. 偏函数后依然可以使用多参数,只要还有参数未固化;而Currying只能使用函数链
  24:  #work  
  25:  partialLogWarning("message", "stack")
  26:  curriedLogWarning("message")("stack")
  27:   
  28:  #2. Currying得到简化的函数方式更自然,而偏函数必须借用高阶函数或手动生成
  29:  curriedLogError  = curriedLog("Error")
  30:  curriedLogUnknownError = curriedLog("Error")("Unknown")
  31:  curriedLogUnknownError2 = curriedLogError("Unknown")
  32:   
  33:  partialLogError = partial(log, "Error")
  34:  partialLogUnknownError = partial(log, "Error", "Unknown")
  35:  partialLogUnknownError2 = partial(partial(log, "Error"), "Unknown")
 
偏函数和Currying有什么用?主要就是从能一个通用函数得到更特定的函数。有一些编程经验的,一定都手工写过偏函数应用吧。
Currying提供了另外一种实现方式。这种方式在函数式编程中更常见。函数式编程思想,不仅在Lisp这样的函数式编程语言中,在更多的语言中也得到了实现和发展,像Python,Javascript乃至C#这样的命令式语言(imperative language)。所以有机会不妨考虑下使用Currying,能否更好地解决问题。 https://www.cnblogs.com/cypine/p/3258552.html

偏函数应用(Partial Application)和函数柯里化(Currying)的更多相关文章

  1. 函数柯里化(Currying)示例

    ”函数柯里化”是指将多变量函数拆解为单变量的多个函数的依次调用, 可以从高元函数动态地生成批量的低元的函数.可以看成一个强大的函数工厂,结合函数式编程,可以叠加出很BT的能力.下面给出了两个示例,说明 ...

  2. Swift函数柯里化(Currying)简谈

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面简单说说Swift语言中的函数柯里化.简单的说就是把接收多 ...

  3. 前端开发者进阶之函数柯里化Currying

    穆乙:http://www.cnblogs.com/pigtail/p/3447660.html 在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接 ...

  4. 应用js函数柯里化currying 与ajax 局部刷新dom

    直接上代码吧 最近读javascript核心概念及实践的代码 感觉很有用 备忘. <div id="request"></div> <script t ...

  5. Javascript函数柯里化(curry)

    函数柯里化currying,是函数式编程非常重要的一个标志.它的实现需要满足以下条件,首先就是函数可以作为参数进行传递,然后就是函数可以作为返回值return出去.我们依靠这个特性编写很多优雅酷炫的代 ...

  6. 深入理解javascript函数进阶系列第二篇——函数柯里化

    前面的话 函数柯里化currying的概念最早由俄国数学家Moses Schönfinkel发明,而后由著名的数理逻辑学家Haskell Curry将其丰富和发展,currying由此得名.本文将详细 ...

  7. JS中的柯里化(currying)

    何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字命名). 柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参 ...

  8. 函数柯里化与偏函数+bind

    简单理解: 1,函数柯里化就是把多参数函数分解为多return的单参数函数: 举个例子(伪代码): function func (a, b, c){ return } 柯里化为 function fu ...

  9. 【转载】JS中bind方法与函数柯里化

    原生bind方法 不同于jQuery中的bind方法只是简单的绑定事件函数,原生js中bind()方法略复杂,该方法上在ES5中被引入,大概就是IE9+等现代浏览器都支持了(有关ES5各项特性的支持情 ...

随机推荐

  1. 【codeforces 510C】Fox And Names

    [题目链接]:http://codeforces.com/contest/510/problem/C [题意] 给你n个字符串; 问你要怎么修改字典序; (即原本是a,b,c..z现在你可以修改每个字 ...

  2. 在全局对象(不是指针)的构造函数里不要对std集合做太多操作

    写MaxvisionOnvif的时候,我用个宏把每个Command类注册到了CommandBuilder里面,通过全局对象初始化实现的,如下: void CommandBuilder::Registe ...

  3. poj 1273最大流dinic算法模板

    #include<stdio.h> #include<string.h> #define N 300 #define inf 0x7fffffff #include<qu ...

  4. python在Linux中安装虚拟环境,区别python2和python3,分别安装模块

    安装虚拟环境的时候遇到的问题,解决的过程很闹心,在这里简单直接的分享出来,就是为了解决问题.  安装虚拟环境(须在联网状态下) $ sudo pip install virtualenv $ sudo ...

  5. Istio是啥?一文带你彻底了解!

    原标题:Istio是啥?一文带你彻底了解! " 如果你比较关注新兴技术的话,那么很可能在不同的地方听说过 Istio,并且知道它和 Service Mesh 有着牵扯. 这篇文章可以作为了解 ...

  6. hibernate即时获取数据库信息

    由于读取数据的时候,Hibernate将第一次读取的内容放到了缓存中,若此时有别的应用修改了数据库中的数据,程序再次读取的时候,内容是从缓存中直接获取,无法反映数据库中的最新状况. 因此,可以设置读取 ...

  7. [转]十五天精通WCF——第八天 对“绑定”的最后一点理解

    转眼已经中断10几天没有写博客了,也不是工作太忙,正好碰到了端午节,然后最近看天津台的爱情保卫战入迷了...太好看了,一直都是回味无穷...而且 涂磊老师话说的真是tmd的经典,然后就这样耽搁了,好了 ...

  8. B1391 [Ceoi2008]order 最大权闭合图 最小割

    啊啊啊,假的题吧!!!我用的当前弧优化T了6个点,其他人不用优化AC!!!震惊!!!当前弧优化是假的吧!!! 到现在我也没调出来...大家帮我看看为啥70.... 来讲一下这个题的思路,就是设一个源点 ...

  9. [python基础] Flasky-表单WTForms支持的html字段和内建函数

    WTForms 支持的HTML 标准字段如表4-1 所示.表4-1 WTForms支持的HTML标准字段字段类型              说 明StringField           文本字段T ...

  10. C#(服务器)与Java(客户端)通过Socket传递对象(序列化 json)

    下面详细讲解实现的关键步骤:          通信关键: C#和java用Socket通信,发送数据和接收数据可以统一采用UTF-8编码,经过测试,使用UTF-8编码可以成功传递对象. 对于Sock ...