函数式编程 订阅
函数式编程是种编程方式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。 [1]  和指令式编程相比,函数式编程强调函数的计算比指令的执行重要。和过程化编程相比,函数式编程里函数的计算可随时调用。 展开全文
函数式编程是种编程方式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。 [1]  和指令式编程相比,函数式编程强调函数的计算比指令的执行重要。和过程化编程相比,函数式编程里函数的计算可随时调用。
信息
外文名
Functional Programming
类    型
编程范式
原    理
将电脑运算视为函数的计算
中文名
函数式编程
主要思想
把运算过程写成嵌套函数调用
基    础
λ演算
函数式编程历史
虽然 λ 演算并非设计来于计算机上执行,但可视为第一个函数式编程语言。1980年代末期,Haskell发布企图集合很多函数式编程研究里的想法。 [2] 
收起全文
精华内容
下载资源
问答
  • 函数式编程

    千次阅读 2020-12-04 16:05:36
    函数式编程 函数式编程是种编程范式,它需要我们将函数作为参数传递,或者作为返回值返还。我们可以通过组合不同的函数来得到想要的结果。 我们来看一下这几个例子: // 全校学生 let allStudents: [Student] = ...

    函数式编程

    image.png

    函数式编程是种编程范式,它需要我们将函数作为参数传递,或者作为返回值返还。我们可以通过组合不同的函数来得到想要的结果。

    我们来看一下这几个例子:

    // 全校学生
    let allStudents: [Student] = getSchoolStudents()
    
    // 三年二班的学生
    let gradeThreeClassTwoStudents: [Student] = allStudents
        .filter { student in student.grade == 3 && student.class == 2 }
    

    由于我们想要得到三年二班的学生,所以我们把三年二班的判定函数作为参数传递给 filter 方法,这样就能从全校学生中过滤出三年二班的学生。

    // 三年二班的每一个男同学唱一首《一剪梅》
    gradeThreeClassTwoStudents
        .filter { student in student.sex == .male }
        .forEach { boy in boy.singASong(name: "一剪梅") }
    

    同样的我们将性别的判断函数传递给 filter 方法,这样就能从三年二班的学生中过滤出男同学,然后将唱歌作为函数传递给 forEach 方法。于是每一个男同学都要唱《一剪梅》😄。

    // 三年二班学生成绩高于90分的家长上台领奖
    gradeThreeClassTwoStudents
        .filter { student in student.score > 90 }
        .map { student in student.parent }
        .forEach { parent in parent.receiveAPrize() }
    

    用分数判定来筛选出 90 分以上的同学,然后用map转换为学生家长,最后用forEach让每个家长上台领奖。

    // 由高到低打印三年二班的学生成绩
    gradeThreeClassTwoStudents
        .sorted { student0, student1 in student0.score > student1.score }
        .forEach { student in print("score: \(student.score), name: \(student.name)") }
    

    将排序逻辑的函数传递给 sorted方法,这样学生就按成绩高低排序,最后用forEach将成绩和学生名字打印出来。

    整体结构

    image.png

    值得注意的是,我们先从三年二班筛选出男同学,后来又从三年二班筛选出分数高于 90 的学生。都是用的 filter 方法,只是传递了不同的判定函数,从而得出了不同的筛选结果。如果现在要实现这个需求:二年一班分数不足 60 的学生唱一首《我有罪》。

    相信大家要不了多久就可以找到对应的实现方法。

    这就是函数式编程,它使我们可以通过组合不同的方法,以及不同的函数来获取目标结果。你可以想象如果我们用传统的 for 循环来完成相同的逻辑,那将会是一件多么繁琐的事情。所以函数试编程的优点是显而易见的:

    • 灵活
    • 高复用
    • 简洁
    • 易维护
    • 适应各种需求变化

    如果想了解更多有关于函数式编程的知识。可以参考这本书籍 《函数式 Swift》

    展开全文
  • React中的函数式编程函数式编程定义的深刻解读 因为一直有了解函数式编程,也知道React是比较遵循函数式编程设计模式的框架,但是一直对函数是编程的定义和理解不是很清楚,到底函数式编程有上面优势,React如何...

    React中的函数式编程及函数式编程定义的深刻解读

    因为一直有了解函数式编程,也知道React是比较遵循函数式编程设计模式的框架,但是一直对函数是编程的定义和理解不是很清楚,到底函数式编程有上面优势,React如何遵循函数是编程,这些都是需要去仔细推敲的,可以让以后的代码写的更为优雅和合理


    什么是函数式编程

    函数是编程是一种设计思想,就像面向对象编程也是一种设计思想。函数式编程总的来说就是用尽量用函数组合来进行编程,先声明函数,然后调用函数的每一步都有返回值,将具体的每一步逻辑运算抽象,封装在函数中。再将函数组合来编写程序。

    特性

    函数是一等公民

    这个特性的意思是函数可以和其他数据类型一样被赋给其他变量,作为参数,作为返回值。在js中函数具有这样特性,所有说js是支持函数式的,在js中的回调函数,闭包的实现就是利用了该特性。

    用声明式,不用命令式

    声明式就是声明一个函数,然后调用函数运算每部都有返回值,命令式就是直接运算

    这里就以一个加法运算作为示例

    #命令式
    let i = 0
    i += 1
    i += 2
    i += 3
    
    #声明式
    let i = 1
    function add(val){
        ...
    }
    i.add(1)(2)(3)
    

    这里的add函数相当于一个黑盒,你不需要知道内部如何实现,你只需要知道add的作用就是相加,而且可以多次不断复用

    没有副作用的纯函数

    首先我们需要理解什么叫纯函数,就是当同样的参数,传入函数后得到结果一样。那我们试想一下什么样的函数会输入同样的结果输出不一样呢。在函数内使用了外部的变量,因为外部的变量是会变化的,或者使用了外部变量,且在每次运行程序结束的时候改变了外部变量。所以函数式变成的另外两条规范就是:

    1. 函数内部不使用外部变量
    2. 函数内部不改变外部变量

    通过这两点,就可以让函数完全与外部独立起来,不受外部影响,也不影响外部。这样函数调用就不会有各种因为外部环境变化产生的问题。

    在这点上可以用slicesplice举个例子

    //纯函数
    let arr = [1,2,3]
    console.log(arr.slice(0,1),arr)
    [1] [1,2,3] //result
    console.log(arr.slice(0,1),arr)
    [1] [1,2,3] //result
    
    //非纯函数
    console.log(arr.splice(0,1),arr)
    [1] [2,3] //result
    console.log(arr.splice(0,1),arr)
    [2] [3] //result
    

    在这里我们可以联想到在js后来常用的一系列方法中,都保持了不修改原对象而返回一个新对象的规范如:reduce,map,findforEach等等

    同时ES6语法中更是推出了了一些新语法,帮助我们来创建返回一个新的对象,如扩展运算符[...arr]可以简单的生成一个新的对象,同时解构可以方便的将对象中的值取出,并赋到一个新的对象上 ,与原来的对象脱离关系。可见js语法是趋向于函数式编程的

    其他

    函数式编程还具有函数柯里化-curry,函数组合调用-cumpose两个规范特性,这个在之后的博客中我会解释。

    React的函数式编程

    从函数式编程的特性,我们可以从很多方面想到React中具有的函数式编程的特征,

    1.React的组件就是一个函数生成,React中的高阶组件就是函数中的高阶函数,如redux中的connectreact-router其实就是放在App外层的高阶函数。原理是相同的,就是将子组件传入父组件中,然后返回一个新的组件,可以复用夫父组件逻辑,这本身也是一种解耦。React页面的渲染过程本质就是函数的嵌套调用过程

    2.React中子组件受父组件传入的props控制,但是子组件不能直接修改props,也就是单项数据流,这样就有点类似于纯函数的特性,不改变外部状态。所以我们在开发组件是,应当尽量将具有副作用的操作交给外部控制,这样的组件才是独立的,也具有高度的适应性。

    3.Redux中这种函数是编程的思想更为明显,Reducer命名来源就是来组员方法reduce,两者都是将一些固定的运算抽象出来,每次都执行相同的任务。所以Reducer内部必须是一个纯函数,而一些请求异步等具有副作用effect的操作都交给中间件来完成。且每次调用完成都返回一个新的对象,不直接修改状态。这样的数据的操作更为清楚,你不需要考虑运行的结果因为其他的原因产生影响

    4**.React和Redux中也使用了很多柯里话和函数组合调用的写法,例:**

    //在redux中写一个中间件,使用了函数柯里化
    const middleware = store => next => action => { 
    };
    

    从上面这些点来看,react是有遵循函数式编程的特性地方,而redux是一个严格遵循函数式变成的插件


    为什么要使用函数式编程

    1.开发速度快,高度使用函数可以不断复用逻辑,函数对外为黑盒可直接无副作用的使用

    2.通过函数名就可以直接理解用处,不需要了解内部实现,接近自然语言,相当于我们使用吹风机,不需要一步步制作吹风机。

    3.代码更清晰,真正调用的代码很简单,所有细节逻辑都封装在函数内

    4,方便并发处理,因为方法为纯函数不影响外部变量,可以随意排放处理顺序。


    总结

    综上所述函数式编程逐渐成为一种编程规范,也被大量的插件所遵循,所以我们在写代码的时候也应该尽量遵守这样的规范,这样有利于我们的代码更为合理,开发起来也更为高效,利于未来的拓展维护。

    展开全文
  • 今天和同事的一番对话,引起了我对java函数式编程和scala函数式编程的思考。 我: java (x,y)->(x+y) x,y,的类型必须提前定义好吗?不能说我(int x,long y)->x+y 同事:如果你说的是函数式编程在java中...

    今天和同事的一番对话,引起了我对java函数式编程和scala函数式编程的思考。

    我:       java (x,y)->(x+y) x,y,的类型必须提前定义好吗? 不能说我(int x,long y)->x+y 
    同事:如果你说的是函数式编程在java中的使用 则(x,y)->(x+y)必然是一个函数式接口的唯一的一个抽象方法
               那此时x,y的类型一定是确定的。他是使用流中的元素作为唯一固定的参数


    我:    唯一固定的参数√明白了。java和scala的函数式编程有根本性的区别
    同事:你说一下。函数式编程应该是固定的,不可能会出现你说的这种情况,有区别 概念本质是不会有偏差的
               有的只是方法的实现出现偏差。

    我:scala是函数式编程语言,函数是一等公民。
            java 类和对象是一等公民
            scala里允许在流的内部定义参数
            而java 只能是list对象作为唯一参数去创建流

    同事:这个 其实java 流是可以改变后面的参数的,map方法其实本质上就是在转化传输的流的元素类型。

    我:    可以改变,但不可以另行定义。

    函数式编程并不是Java新提出的概念,其与指令编程相比,强调函数的计算比指令的计算更重要;与过程化编程相比,其中函数的计算可以随时调用。

    当然,大家应该都知道面向对象的特性(抽象、封装、继承、多态)。其实在Java8出现之前,我们关注的往往是某一类对象应该具有什么样的属性,当然这也是面向对象的核心--对数据进行抽象。但是java8出现以后,这一点开始出现变化,似乎在某种场景下,更加关注某一类共有的行为(这似乎与之前的接口有些类似),这也就是java8提出函数式编程的目的。
     

     

    -------------------- 2020/09/18
    java1.8使用函数式编程的推手:在计算机资源不再是严重限制时(函数式编程比指令编程更消耗资源),提高开发效率就是一个摆在眼前的问题。

     

    Java 认为局部副作用是优质代码的基石;而 FP 认为它们是魔鬼。

    展开全文
  • 什么是函数式编程? C语言为何不是函数式语言? 函数式语言有两个个主要的特点:1. 函数是“头等公民”。2. 数据的“immutability”. 操作的“无副作用”, 这规避了‘锁’。 函数式编程的函数是指数学上的函数:...

    什么是函数式编程? C语言为何不是函数式语言?

    函数式语言有两个主要的特点:1. 函数是“头等公民”。2. 数据的“immutability”(不变;永恒性;不变性;). 操作的“无副作用”,
    这规避了‘锁’。
    函数式编程的函数是指数学上的函数:给定输入固定的输出,没有副作用。任何语言都可以用函数式的风格,
    只是难易不同罢了。
    比如有函数 y = f(x). 和 函数 x = g(z); 可以组成复合函数 y=f(g(z));

    对于第二个问题,C为何不是函数式语言?

    因为这种效果在C里面不能实现: y=f(g(z));

    int f(int x) { print x;}             ===== y = f(x)
    int g(int z) {return z;}             ===== x = g(z)
    int f1(int (*g)(int)) { print g(z);} ===== y = f1(g(z))
    
    


    从上面的函数定义可以看到,当函数f(x)的参数定义为int时,便不能将函数g(z)作为形参传递给它。(函数指针与int参数类型不匹配)
    反过来看函数f1()也不能接受int作为参数了。

    于是,C达不到数学上函数的那种效果。

    而在clojure里面却可以。

    (defn f [x] (print x))    ======= y = f(x)
    (defn g [z] z)            ======= t = g(z)



    这时,(f (g 3)) 和 (f 3) 的结果是一样的,达到了数学上的效果。
    再者,C也不具有函数式语言的特点2.

    常见的函数式语言有哪些?

    coljure、scala、Haskell。

    为什么如python/javascrip这些语言不是函数式语言呢,因为他们不具备函数式语言的特点2.
    ————————————————
    原文链接:https://blog.csdn.net/lx1848/article/details/77619881

     

    毫无干货的带你理解什么是函数式编程

     

    世界模型

    如果让你搭建一个模型来描述这个世界你会怎么做?

    面向对象

    面向对象之父Alan Kay给我们带来了一种抽象化世界的方法。

    一切事物皆对象,通过面向对象的方式,将现实世界的事物抽象成对象,现实世界中的关系抽象成类、继承,帮助人们实现对现实世界的抽象与数字建模。

    因此我们有了面向对象式的编程式范。

    函数式

    这里本来应该引入《范畴论》的概念,不过在这里引入似乎会把事情搞的更复杂,所以先不去理会它,直接看结果。

    世界就是由事物和事物之间的关系构成的

    下面是一个空无一物的世界:

     

    image.png

    世界中有一个a:

    image.png

     

    世界中有了事物ab,还有他们之间的关系f,即使他们之间没关系也可以用f来表示,只不过f等于null

    image.png

     

    我们的世界更加丰富了:

    image.png

    如果我们继续这样画下去我们可以画出一个足够复杂的世界。不过到这里已经足够了。

    • 把关系f作用到a上可以得到b
    • 把关系g作用到b上可以得到c
    • 把关系h作用到a上可以得到c
    • 其中h = g.f

    让我们再次进行抽象,抽取他们的共性部分。

     

    image.png

    所以我们得到了一个结构:a表示事物,f表示关系。把f作用到a上我们就可以得到b

    image.png

     

    要知道一切真理都是包含在特定的上下文中的(除了这一句)。所以我们的事物a也应该包含在上下文中它才是真正的a,所以我们得到的b也是上下文中的b

    image.png

    (这张图看起来像是a是印在盒子上的而不是在盒子内部,不要在意这些细节它是在盒子里的)
    我们来用一个算式来验证一下模型计算1+2+4的值:

    image.png

     

    我们再来一个用户登录的模型,用户名和密码长度都大于0的时候才可以登录:

    image.png

     

    上面的做法和直接写语句有什么不同?

    - (BOOL)canLoginUserName:(NSString *)username password:(NSString *)password{
        if (username.length > 0 && password.length > 0) {
            
        }else{
            
        }
    }
    

    拆分方式不同,图中拆分成了:

    • username和它的关系length>0,得到结果YES
    • password和它的关系length>0,得到结果YES
    • 两个YES和它的关系&&,得到结果YES

    结论:

    • 如果你把世界拆分成,对象你就得到了面向对象
    • 如果你把世界拆分成事物事物之间的关系你就得到了函数式

    好了道友们,看到这里你可以怀着愉快的心情关上电脑,闭上眼睛,深呼吸,思考一下如何按照事物事物之间的关系的方式来拆分世界,你就已经掌握了函数式编程的思想。

    简单对比

    • 面向对象的世界里我们是把事物抽象成对象,然后通过封装继承多态来演示他们之间的关系。
    • 函数式的世界里把世界抽象成事物事物之间的关系,用这种方式实现世界的模型。

    面向对象的编程更有人情味一些更社会化。比如你想要买一辆汽车,想要托人帮忙砍价。恰好你同学的朋友的大表哥的二嫂子在4s店工作。你就需要:

    import "同学"
    import "朋友"
    import "大表哥"
    import "二嫂子"
    

    然后再调用二嫂子.砍价();

    函数式编程则更“冰冷”一些,像是工厂里的流水线不停的运转,只要你放入材料就可以在出口处拿到产品。而且它对外部环境没有依赖,只需要将流水线搬走就可以在任何地方生产。不需要找同学的朋友的大表哥的二嫂子来帮忙了。


    整理了几篇干货资料,有兴趣的道友可以看看:

    展开全文
  • java8新特性 lambda Stream map(函数式编程)

    万次阅读 多人点赞 2016-08-20 15:04:42
    java8新特性 lambda Stream map(函数式编程) 牛刀小试:使用Java8新特性获取股票数据https://blog.csdn.net/u014646662/article/details/82936131 Java8实战.pdf 下载:...
  • 什么是函数式编程 引入 概念 我们知道,在数学中,函数可以有如下形式: f(X) = Y ,即一个函数f ,以X作参数,返回输出结果Y。 据此,我们可以归纳一个函数: 函数必须接受一个参数 函数必须返回一个值 函数应该...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 42,762
精华内容 17,104
关键字:

函数式编程