Skip to content

Latest commit

 

History

History
68 lines (45 loc) · 4.21 KB

functional-programming.md

File metadata and controls

68 lines (45 loc) · 4.21 KB

[[toc]]

要解决的问题

如何深入准确地理解并掌握一门高阶语言的特性

新的编程语言层出不穷,老的快速演进;有的语言追求纯粹,有的以解决工程问题为主;有的语法追求人性化,有的为机器而生;有些语言特性的变化润物无声,有些翻天覆地。现实的复杂性使得没有任何一门语言能够满足所有场合的需求,程序员需要准确、深入,快速地掌握一门语言的特性。

解决方案

回答以下问题:

  • 该特性有哪些特点?
  • 该特性的“母语”是什么?“母语”会成为其他语言实现的参照或模版。通过学习母语加深理解。
  • 该特性有哪些理论基础?理论都很抽象,不易快速掌握,如能了解其核心思想会让对语言特性的理解变得自然顺畅。
  • 该特性在其他语言中是如何实现的?各种原因常常会导致一种特性在不同语言中的实现存在很大的差别,有些语言通过语法糖来实现,有些在编译器、解释器上实现,有些通过SDK来实现。理解这些差异能避免踩到雷,减少不必要的BUG,保证程序的性能和健壮性。

解决方案案例

Functional Programming

函数式编程(FP,functional programming)作为一种编程范式,其很多特性已经被引入到各种语言中,包括静态和动态类型的语言。例如:C++、Java、Scala,Go以及Javascript、Perl、Python等。Java在1.8版本中支持了FP的很多特性。

FP的特点

  • FP强调如何描述问题,剩下的交给计算机来做;IP强调如何让计算机一步一步地执行输入的指令来解决问题。
  • 函数是“一等公民”。函数像参数一样传入、返回,习惯了命令式编程,需要改变已有的思维习惯。
  • 函数都是无状态的。相同的输入必定产生相同的输出,除了入参,函数的结果不会受Context的影响。
  • 高阶函数。一个或多个函数作为入参,或返回结果是一个函数的函数。
  • 无副作用。函数不会改变Context。
  • 函数组合。函数之间可以组合完成一个功能。
  • 惰性求值。
  • 异常被视作运算结果的一个特殊值进行处理。

FP的“母语”:Haskell

尽管Haskell不是最早出现的FP语言,但它是目前支持FP特性最全面,其他语言实现FP特性的参照语言之一。

FP的理论基础:范畴论(Category theory)

范畴是比集合更复杂的数学工具,范畴由三部分组成:

  • 一组对象
  • 一组态射(morphisms)。每个态射会绑定两个对象,假如f是从源对象A到目标对象B的态射,记作:f:A -> B
  • 态射组合。假如h是态射f和g的组合,记作:h = g o f

集合不去研究元素之间的关系,而范畴核心就是态射,也就是对象之间的关系,而且对象本身也可以是态射。要搞清楚范畴理论,前提需要熟悉抽象代数,群论等理论,非一早一夕能掌握,理解范畴论的思想,核心的概念也就达到了学习的目的。 事实上,Haskell中的类型和函数构成一个范畴Hask,Haskell中的类型是Hask范畴的对象,Haskell中的函数是Hask的态射。

Haskell中的Functor定义如下:

class Functor (f :: * -> *) where
  fmap :: (a -> b) -> f a -> f b

class表示Functor是一个type class,可以理解为一组方法的集合;class的实例就是Haskell中的类型,例如:Int, Char,[]。f为Hask中的态射,从一种类型指向另外一种类型。Functor包括一个方法fmap,它输入一个函数:a->b,一个f a,输出f b。范畴论中,Functor对应函子,它是两个范畴之间的态射,即:F:C->D,其中C,D是两个范畴。f是函子中作用于对象上的部分,fmap是是函子中作用于态射上的部分。例如下图中(+1)表示元素+1的函数,即a->bf[]类型,这里把整数态射为列表,执行的结果就是原列表元素加1得到一个新列表。

ghci>fmap (+1) [0..9]
[1,2,3,4,5,6,7,8,9,10]

Haskell快排示例

<<< @/../functional-programming/haskell-sample.hs

Java函数式编程示例

<<< @/../functional-programming/TestFunction.java