当前位置: 首页 > news >正文

读函数式编程思维

读函数式编程思维

总的说下

这本书总得讲了下函数式思维,以及用各种语言来掩饰了下函数式思维。。。后面我用 swift 来演示吧

第一章 为什么要用函数式思维

函数式思维是编程范式的转换,最重要的是我们要正确的掌握语言给我们提供的特性,才能把一个语言用好

随着计算机性能提升以及编译器的不断优化,可以把一些控制权(比如内存管理,多线程等琐碎的语言细节)交给运行时来处理,用更好和更简洁的抽象来解决我们的问题

第二章 转变思维

命令式编程是按照“程序是一系列改变状态的命令”来建模的一种编程风格。

比如 for 循环处理数组,我们平时使用的时候,是通过确定初始状态,然后每次迭代都执行循环的命令,在循环的命令里面我们完成业务逻辑

函数式方法,讲程序描述为表达式和变换,以数学方程的形式建立模型,并尽可能避免可变状态

通过将数据集,进行 filter,map,reduce 等转换,得到我们想要的结果,以一种定义或是描述式的方式来处理

所有的函数式语言里面都会以不同的形式提供 filter(过滤),map(映射),reduce(折叠或者化约)

第三章 责权让渡

函数式思维的好处之一,是能够将低层次细节(如垃圾收集)的控制权移交给运行时,从 而消弭了一大批注定会发生的程序错误。开发者们可以一边熟视无睹地享受着最基本的抽 象,比如内存,一边却会对更高层次的抽象感觉突兀。然而不管层次高低,抽象的目的总 是一样的:让开发者从繁琐的运作细节里解脱出来,去解答问题中非重复性的那些方面。

  1. 不再使用类似 forwhile 之类的迭代,而是使用高阶函数,比如 map
  2. 闭包,关注函数执行的上下文,而非通过闭包去控制状态
  3. 柯里化,实现函数工厂,模板方法,隐藏参数
  4. 递归,递归更加优雅,以及更容易让我们考虑无限的集合
  5. Stream 和作业顺序重排

第四章 用巧不用蛮

记忆,和缓存类似,但是不需要我们来管理,只需要在函数调用后,告诉函数需要记忆此次调用的结果,下次使用相同参数调用的时候,就不需要再次进行计算了

swift 中的参考 memoize

缓求值,不到逼不得已,不去对函数进行求值。

缓求值可以处理无限长的序列,减少存储空间占用,缓求值还有利于运行时产生高效代码

第五章 演化的语言

在面向对象的世界里,我们针对具体问题,建立专门的数据结构,以方法的形式将专门的操作关联在数据结构上。

函数式编程,只使用很少的一组关键数据结构(list,set,map)搭配专为这些数据结构深度优化过的操作。

比起在定制的类结构上做文章,把封装的单元缩小到函数级别,有利于在更基础的层面上 更细粒度地实施重用。

Clojure 很好地发挥了这方面的优势,例如在 XML 的解析问题上。 Java 语言的 XML 解析框架数量繁多,每一种都有自己的定制数据结构和方法语义(如 SAX 和 DOM 都是自成一体)。Clojure 的做法相反 ,它不鼓励使用专门的数据结构,而是 将 XML 解析成标准的 Map 结构。而 Clojure 有极为丰富的工具可以与 map 结构相配合

使用模式匹配来替代长长的 if

要想契合问题域的表达习惯,可以利用运算符重载来改变语言的外貌,不必 创造全新的语言。

函数式数据结构,使用 Either 表示两种结果的返回值,使用 Option 来表示有为空返回值的类型

第六章 模式与重用

函数式语言有函数式语言的设计模式,传统的对于函数式语言来说,因为语言的特性,让部分模式变得没有意义了,但是部分问题还是存在,他们在函数式的世界里面,通过其他的方法来解决了

传统设计模式在函数式编程的世界中大致有三种归宿。

  • 模式已被吸收成为语言的一部分。
  • 模式中描述的解决办法在函数式范式下依然成立,但实现细节有所变化。
  • 由于在新的语言或范式下获得了原本没有的能力,产生了新的解决方案(例如很多问题都可以用元编程干净利落地解决,但 Java 没有元编程能力可用)。

函数级别的重用

因为函数式编程的特点,重用的最小单位变成了函数,并且程序由多个函数组合而成。

Template Model,通过使用函数变量,进行了化简,减少耦合

Strategy 模式,更加灵活

Flyweight 模式,使用记忆来实现

Factory 模式和柯里化,柯里化就是产出函数的工厂

以结构为载体的代码重构需要考虑整个类的关系网,可以很好的减少耦合的情况。

第七章 现实应用

Java 8 中的函数式接口,Option 类型,Stream,都是函数式语言在 Java 语言中的应用

函数试的构架,贯彻“值不可变”,学习从值不可变的角度去思考

可变的状态与测试数量有直接的关联:可变的状态越多,要求的测试也越多。

实现一个值不可变的 Java 类,我们需要做到以下事情。

  • 把所有的字段都标记为final。Java 要求被标记为 final 的字段,要么在声明时初始化,要么在构造器中初始化。不要 在意 IDE 大惊小怪地提醒我们字段没有在声明位置上初始化,当我们在构造器里写好 相关的初始化代码,IDE 就会明白过来。

  • 把类标记为final,防止被子类覆盖。 如果类可以被覆盖,类中的方法也就有可能被改变行为,因此以防万一,我们干脆禁止 子类化。Java 的 String 类就采取了这样的防范策略。

  • 不要提供无参数的构造器。 一个值不可变的对象,它的一切状态都必须通过构造器来设定。假如我们没有需要设定 的状态,那建立这么一个对象又有何必要呢?在无状态的类里面安排几个静态方法就足 够了。所以说,值不可变的类根本不应该出现无参数的构造器。假如我们受到某些框架 的限制,不得不提供无参数的构造器,这时可以考虑能否用一个私有的无参数构造器来 满足框架的要求(私有的构造器仍然可以通过反射来访问)。 JavaBeans 的标准规定要有默认构造器,我们摒除无参数构造器违反了这条规定。不过 反正 JavaBeans 里有各种 setXXX 方法存在,本身就不可能是值不可变的。

  • 提供至少一个构造器。 构造器是我们在对象里添置状态的最后机会!

  • 除了构造器之外,不要提供任何制造变化的方法。我们不但要避免沿袭 JavaBeans 风格的 setXXX 方法,还必须小心防范,不能返回任何 值可变的对象引用。标记了 final 的对象引用并不等于它所指向的一切都不可改变。因 此,我们需要预防性地复制所有通过 getXXX 方法返回的对象引用。

对于 web 框架,函数式语言回很合适,因为整个 web 就是一系列从请求到响应的变换

相关文章:

  • IE中用JS让页面全屏的方式(达到F11的 效果)
  • 利用DataURL技术在网页上显示图片
  • iOS音频AAC视频H264编码 推流最佳方案
  • 【十大经典数据挖掘算法】C4.5
  • logstash推送mysql慢查询日志
  • 51cto博客第一篇
  • c语言:将三个数按从大到小输出。
  • 正则与JS中的正则
  • JAVA实现发送电子邮件
  • JS组件系列——表格组件神器:bootstrap table
  • JavaScript数组使用sort排序
  • junit测试时,出现java.lang.IllegalStateException: Failed to load ApplicationContext
  • 我的Android进阶之旅------Android【设置】-【语言和输入法】-【语言】列表中找到相应语言所对应的列表项...
  • BZOJ1075 : [SCOI2007]最优驾车drive
  • SharePoint自动化系列——Create a local user and add to SharePoint
  • chrome扩展demo1-小时钟
  • Java|序列化异常StreamCorruptedException的解决方法
  • Service Worker
  • SQLServer之创建显式事务
  • unity如何实现一个固定宽度的orthagraphic相机
  • vue的全局变量和全局拦截请求器
  • 从零开始学习部署
  • 前端路由实现-history
  • 前嗅ForeSpider教程:创建模板
  • 深度学习中的信息论知识详解
  • 通过几道题目学习二叉搜索树
  • 网页视频流m3u8/ts视频下载
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • 转载:[译] 内容加速黑科技趣谈
  • AI又要和人类“对打”,Deepmind宣布《星战Ⅱ》即将开始 ...
  • ​iOS实时查看App运行日志
  • #使用清华镜像源 安装/更新 指定版本tensorflow
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (C++17) std算法之执行策略 execution
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (三十五)大数据实战——Superset可视化平台搭建
  • (算法)Game
  • (正则)提取页面里的img标签
  • (转载)利用webkit抓取动态网页和链接
  • * 论文笔记 【Wide Deep Learning for Recommender Systems】
  • .bat批处理(六):替换字符串中匹配的子串
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .NET/C# 的字符串暂存池
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .NET框架类在ASP.NET中的使用(2) ——QA
  • @autowired注解作用_Spring Boot进阶教程——注解大全(建议收藏!)
  • @NoArgsConstructor和@AllArgsConstructor,@Builder
  • @Transactional类内部访问失效原因详解
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [2024] 十大免费电脑数据恢复软件——轻松恢复电脑上已删除文件
  • [C#]OpenCvSharp结合yolov8-face实现L2CS-Net眼睛注视方向估计或者人脸朝向估计