响应式编程 函数式编程

根据您要求的对象, 函数式编程 (FP)是一种应运而生的开明编程方法,或者是一种在实践中几乎没有实际好处的过于学术化的方法。 在本文中,我将解释什么是函数式编程,探讨其好处,并推荐用于学习函数式编程的资源。

语法底漆

本文中的代码示例使用Haskell编程语言。 对于本文,您需要了解的只是基本的函数语法:

even :: Int -> Bool
even = ...    -- implementation goes here

这定义了一个名为even的单参数函数。 第一行是类型声明 ,它声明甚至接受一个Int并返回一个Bool 。 该实现遵循一个并包含一个或多个方程 。 我们将忽略实现(名称和类型足以说明问题):

map :: ( a -> b ) -> [ a ] -> [ b ]
map = ...

在此示例中, map是一个带有两个参数的函数:

  1. (a-> b) :将a变成b的 a函数
  2. [A]: 一个列表

并返回b的列表。 再次,我们不在乎定义-类型更有趣! ab是可以代表任何类型的类型变量 。 在下面的表达式中, aIntbBool


  map even [ 1 , 2 , 3 ] 

评估为[Bool]


  [ False,True,False ] 

如果看到其他您不理解的语法,请不要惊慌。 完全理解语法不是必需的。

关于函数式编程的神话

编程与开发

让我们从消除常见的误解开始:

  • 函数式编程不是命令性或面向对象编程的竞争对手或对立面。 这是错误的二分法。
  • 函数式编程不仅是学者的领域。 的确,函数式编程的历史扎根于学术界,诸如Haskell和OCaml之类的语言是流行的研究语言。 但是如今,许多公司都将函数式编程用于大型系统,小型专用程序以及两者之间的所有内容。 甚至每年都有一次针对函数式编程商业用户的会议; 过去的程序可以洞察功能编程在行业中的使用方式以及由谁使用。
  • 函数式编程与monad无关,也与任何其他特定抽象无关。 对于围绕该主题的所有麻烦,monad只是法律的抽象。 有些东西是单子,有些不是。
  • 函数式编程并不是特别难学。 某些语言可能具有与您已经知道的语法或评估语义不同的语法,但是这些差异是肤浅的。 函数式编程中有密集的概念,但是其他方法也是如此。

什么是函数式编程?

从本质上讲,函数式编程就是使用函数( 数学函数)进行编程。 函数的结果仅取决于参数,并且没有副作用,例如I / O或状态突变。 通过将功能组合在一起来构建程序。 组合功能的一种方法是功能组合

( . ) :: ( b -> c ) -> ( a -> b ) -> ( a -> c )
( g . f ) x = g ( f x )

infix函数将两个函数组合为一个,将g应用于f的输出。 我们将在接下来的示例中看到它。 为了进行比较,Python中的相同函数如下所示:

def compose ( g , f ) :
return lambda x: g ( f ( x ) )

函数式编程的优点在于,因为函数是确定性的并且没有副作用,所以您始终可以用函数的结果替换函数应用程序。 用equals代替equals可以进行方程式推理 。 每个程序员都必须对自己的代码和其他人进行推理,而方程式推理是实现此目的的绝佳工具。 让我们来看一个例子。 您遇到以下表达式:


  map even . map ( + 1 ) 

这个程序做什么? 可以简化吗? 方程式推理使您可以通过一系列替换来分析代码:

map even . map ( + 1 )
map ( even . ( + 1 ) )         -- from definition of 'map'
map ( \ x -> even ( x + 1 ) )  -- lambda abstraction
map odd                   -- from definition of 'even'

我们可以使用方程式推理来理解程序并优化可读性。 Haskell编译器使用方程式推理来执行多种程序优化。 没有纯函数,方程式推理要么不可能,要么需要程序员的不懈努力。

功能编程语言

您需要一种编程语言才能进行功能编程?

在没有高阶函数 (能够将函数作为参数和返回函数传递), lambda (匿名函数)和泛型的语言中有意义地进行函数编程是很困难的。 大多数现代语言都具有这些功能,但是不同语言对功能编程的支持程度有所不同。 获得最佳支持的语言称为功能编程语言 。 其中包括静态类型的HaskellOCamlF#Scala ,以及动态类型的ErlangClojure

即使在函数式语言之间,利用函数式编程的距离也存在很大差异。 使用类型系统有很多帮助,特别是如果它支持类型推断 (因此您不必总是键入类型)。 本文没有余地进行详细介绍,但是可以肯定地说,并非所有类型系统都是一样的。

与所有语言一样,不同的功能语言强调不同的概念,技术或用例。 选择语言时,考虑它对函数式编程的支持程度以及它是否适合您的用例非常重要。 如果您坚持使用某些非FP语言,则仍可以在该语言支持的范围内应用功能编程来受益。

不要打开那扇陷阱门!

回想一下,函数的结果仅取决于其输入。 las,几乎所有编程语言都具有打破这一假设的“功能”。 空值,类型case( instanceof ),类型转换,异常,副作用和无限递归的可能性是陷阱门,它们破坏了方程式推理并削弱了程序员对程序的行为或正确性进行推理的能力。 ( 总计语言 ,没有任何陷阱门,包括Agda,Idris和Coq。)

幸运的是,作为程序员,我们可以选择避免这些陷阱,并且如果我们受到纪律处分,我们可以假装陷阱门不存在。 这个想法称为快速和宽松推理 。 它不花任何钱-几乎无需使用陷阱门就可以编写任何程序-避免它们,您将赢得等式推理,可组合性和重用性。

让我们详细讨论异常。 该活板门破坏了公式推理,因为这种类型未反映异常终止的可能性。 (如果文档甚至提到了可能引发的异常,请给自己一个幸运的机会。)但是没有理由不能让我们拥有一个包含所有故障模式的返回类型。

避免陷井门是一个在其中语言功能可以发挥很大作用的领域。 为了避免异常,可以使用代数数据类型对错误条件进行建模,如下所示:

-- new data type for results of computations that can fail
--
data Result e a = Error e | Success a

-- new data type for three kinds of arithmetic errors
--
data ArithError = DivByZero | Overflow | Underflow

-- integer division, accounting for divide-by-zero
--
safeDiv :: Int -> Int -> Result ArithError Int
safeDiv x y =
if y == 0
then Error DivByZero
else Success ( div x y )


在此示例中的权衡是,您现在必须使用Result ArithError Int类型的值,而不是普通的旧Int ,但是有一些处理此问题的抽象方法。 您不再需要处理异常,并且可以使用快速和宽松的推理,因此总的来说,这是双赢。

免费定理

大多数现代的静态类型语言都具有泛型 (也称为参数多态 ),其中函数是在一种或多种抽象类型上定义的。 例如,考虑一个列表中的函数:

f :: [ a ] -> [ a ]
f = ...

Java中的相同函数如下所示:


  static < A > List < A > f ( List < A > xs ) { ... } 

编译后的程序证明了该函数可以与类型a的 任何选择一起使用 。 考虑到这一点,并采用快速和宽松的推理,您能算出函数的作用吗? 知道类型有帮助吗?

在这种情况下,类型不能确切告诉我们函数的功能(它可以反转列表,删除第一个元素或其他很多东西),但是可以告诉我们很多东西。 只需从类型中,我们就可以得出有关函数的定理:

  • 定理1 :输出中的每个元素都出现在输入中; 它不可能将a添加到列表中,因为它不知道a是什么或如何构造a。
  • 定理2 :如果在列表上映射任何函数然后应用f ,则结果与应用f然后映射相同。

定理1可帮助我们了解代码在做什么,定理2可用于程序优化。 我们只是从类型中学到了所有这些! 这种结果(从类型中得出有用定理的能力)称为参数性 。 因此,类型是函数行为的部分(有时是完整的)规范,是一种经过机器检查的文档。

现在该轮到利用参数化了。 您可以从map(。)的类型或以下函数得出什么结论?

  • foo :: a->(a,a)
  • 栏:: a-> a-> a
  • baz :: b-> a-> a

学习函数式编程的资源

也许您已经确信函数式编程是编写软件的更好方法,并且您想知道如何入门? 有几种学习函数式编程的方法。 这是我推荐的一些(我承认,对Haskell有强烈的偏见):

  • UPenn的CIS 194:Haskell简介对函数式编程概念和实际的Haskell开发进行了扎实的介绍。 课程材料可用,但讲座不可用(您可以查看几年前布里斯班功能编程小组关于CIS 194的系列演讲 )。
  • 好的入门书籍包括Scala中的函数式编程, 与Haskell进行函数式思考以及从第一原理开始的Haskell编程
  • Data61 FP课程 (fka, NICTA课程)通过类型驱动的开发讲授基础抽象和数据结构。 回报是巨大的,但是设计很难 ,因为它起源于培训工作坊,所以只有在您知道愿意指导您的函数式程序员的情况下,才尝试这样做。
  • 开始使用正在处理的任何代码进行函数式编程。 编写纯函数(避免不确定性和变异),使用高阶函数和递归而不是循环,利用参数性提高可读性和重用性。 许多人通过试验和体验各种语言的好处来开始进行函数式编程。
  • 加入您所在地区的功能编程用户组或研究组,或开始一个活动组,并注意进行功能编程会议(新的会议一直在弹出)。

结论

在本文中,我讨论了什么是函数编程以及什么不是函数编程,并讨论了函数编程的优点,包括方程式推理和参数化。 我们了解到,您可以使用大多数编程语言进行某些函数式编程,但是语言的选择会影响您受益,因为Haskell等函数式编程语言可以提供最多的功能。 我还推荐了用于学习函数式编程的资源。

函数式编程是一个广阔的领域,还有许多更深入(更密集)的主题正在等待探索。 我不愿提及一些具有实际意义的东西,例如:

  • 镜头和棱镜(一流的,可组合的吸气剂和吸气剂;非常适合处理嵌套数据);
  • 定理证明(为什么您可以在证明自己正确的情况下测试代码?);
  • 惰性评估(让您使用可能无限的数据结构);
  • 和类别理论(函数式编程中许多美丽而实用的抽象的起源)。

我希望您喜欢函数式编程的入门知识,并能从中受益于这种有趣而实用的软件开发方法。

本文是根据CC BY 4.0许可证发布的。

翻译自: https://opensource.com/article/17/4/introduction-functional-programming

响应式编程 函数式编程

响应式编程 函数式编程_函数式编程简介相关推荐

  1. python编程求导数_面向对象编程 —— java实现函数求导

    首先声明一点,本文主要介绍的是面向对象(OO)的思想,顺便谈下函数式编程,而不是教你如何准确地.科学地用java求出函数在一点的导数. 一.引子 defd(f) :defcalc(x) : dx= 0 ...

  2. python支持多种编程范式吗_聊聊编程范式

    标签: 编程语言有很多种流派和思想,有一些编程语言同时支持多种编程范式. 静态类型编程范式 采用静态类型编程范式的编程语言,其变量需要明确指定类型.代表语言:C,C++,Pascal,Objectiv ...

  3. python编程 迷你世界_迷你编程下载-迷你世界迷你编程下载 v1.0官方版--pc6下载站...

    迷你世界迷你编程是一款图形化编程软件,可以帮助青少年学习基础的编程知识,提高逻辑思维能力,迷你世界迷你编程还能让用户直观的感受到编程效果,对编程产生兴趣.. 相关软件软件大小版本说明下载地址 迷你世界 ...

  4. python编程 迷你世界_迷你编程电脑版|迷你世界迷你编程下载 v1.0官方版 - 绿点软件站...

    迷你世界迷你编程是一款简单易学图形化编程软件,软件采用图形化的编程方式,过程就像组合积木一样简单,不但可以帮助青少年学习基础的编程知识,也提高了数学逻辑思维能力,还可以让孩子们感受到创造三维立体世界的 ...

  5. 响应式网页设计代码_消除响应式网站建设设计中的缺陷

    在过去的5年里,移动流量的份额增长了20%,现在响应式网站设计已经被认为是理所当然的了.到2020年,您可以通过手机几乎可以访问任何网站,它会很好用.大多数用户如果看到一个网站在他们的智能手机或平板电 ...

  6. elementui 响应式导航栏网站_什么是响应式网站?响应式网站的优势介绍

    响应式网站的含义 响应式网站指的是同一个网站,可以支持在iPai.手机.电脑以及其他各种设备上能够正常访问网站,它可以根据设备屏幕大小进行等比缩,不会影响到最终的展示效果. 举例说明: 浏览器窗口最大 ...

  7. css响应式网格布局生成器_如何使用网格布局模块使用纯CSS创建响应表

    css响应式网格布局生成器 TL; DR (TL;DR) The most popular way to display a collection of similar data is to use ...

  8. 响应式移动端框架_简单,响应式,移动优先导航

    响应式移动端框架 我们将构建一个简单的响应式网站导航. 我们的解决方案将帮助我们强调页面的内容 ,可以说是设计移动设备时的重中之重. 不会涉及JavaScript,我们将通过Mobile First方 ...

  9. 纯函数式编程语言_函数式编程正在接管具有纯视图的UI。

    纯函数式编程语言 by Bobby Schultz 由Bobby Schultz 函数式编程正在接管具有纯视图的 UI . (Functional Programming is taking over ...

  10. python函数式编程什么意思_函数式编程中“部分函数”到底是什么意思?

    答案说明了一切,我将在每种语言中添加一个示例:def add(x,y): return x+y f = add(1) print(f(3)) f = add(1) TypeError: add() m ...

最新文章

  1. python+flask+vue开发(1)--虚拟环境创建
  2. python项目归纳总结-这4个Python实战项目,让你瞬间读懂Python!
  3. Win32下内存分配简单示例 - 使用CFree
  4. attr和prop的区别
  5. SQL 强制指定索引加快查询速度
  6. easyUI layout 中使用tabs+iframe解决请求两次方法
  7. 彻底删除SQL Server2005(转)
  8. 图的深度优先遍历和广度优先遍历(附例题)
  9. java 动态读取配置文件_java读取配置文件的几种方法
  10. GEOMETRIC APPLICATIONS OF BSTS
  11. 宝塔面板干什么用的?
  12. 汇编语言--寄存器间接寻址
  13. Linux内存管理(二):ARMv8 地址转换
  14. yapi 数据库隔天数据就全没了_Yapi 部署
  15. 【Python实战项目】全球疫情数据采集 + 可视化展示
  16. tp3.2打印mysql查询语句_[tp3.2.1]sql查询语句(一)
  17. 避免内容失去焦点_痛楚难以避免,而磨难可以选择
  18. 我的世界服务器怎么做无限的弓,我的世界怎么用命令方块做无限弓?
  19. C#卸载程序需要密码/防卸载功能
  20. java noi和io

热门文章

  1. 跨代引用、记忆集、卡表
  2. 用python可以做什么有趣的事情_用python真的可以做很多有趣的事!我自己做了些小项目!...
  3. 有趣的三次握手和四次挥手问题
  4. 看别人的世界,品自己的人生
  5. PPT中两端对齐的按钮
  6. HDU 5172 GTY's gay friends (线段树)
  7. python安装后桌面没有显示图标_为什么菜单图标不显示?
  8. 浅谈知识图谱---neo4j
  9. 搜狗地图 android wear,Android Wear多款来袭!搜狗地图独家内置
  10. LAMP环境搭建wordpress