haskell编程学习笔记(一) 高阶函数

我今天所记录的学习笔记主要来自3个来源:

  1. 这段时间学习haskell语言编程的实践经验
  2. John Backus的Can Programming Be Liberated from the von Neumann Style?  由于数学基础过于薄弱,我只能说“读完”而不是“读懂”这篇论文,强烈建议大家读原文
  3. John Hughes why functional programming matters
John Backus的论文中所述的函数式编程VS冯诺依曼式编程类似于haskell中提到的函数式编程VS命令式编程(希望我没有误读)

 我用java和haskell分别实现该论文中的求内积方法,即,给定[a,b,c]和[x,y,z]求 sum = a*x + b*y + c*z
public static int innerProduct(int[] xs,int[] ys){
        int sum = 0;                                                        //(1)
        for ( int i=0;i<xs.length;i++){                             //(2)
                sum = sum + xs[i] * ys[i];
        }
        return sum;
}                                                                                 //(3)
(1) java的实现必须多定义一个变量
(2) 循环变量i 并不存在于问题中(即求 sum = a*x + b*y + c*z 这个问题里并没有i的存在)
(3) John Backus的论文指出我们必须在脑子里“运行”这个传统编程语言的代码才能理解其含义。 
也就是说我们读这段代码的时候其实是把自己当作人肉计算机在脑子里顺序解释执行这些代码。

innerProduct :: [Int] -> [Int] -> Int
innerProduct xs ys = sum $ zipWith (*) xs ys
 haskell的版本是个典型的函数式语言实现,展现了高阶函数(high order function)的威力,并且避免了上述的3个问题
zipWith 是个函数, 接受3个参数,形如: zipWith f xs ys,其中第一个参数f是另一个函数(函数当作参数传递),此函数接受两个参数并返回一个结果,在这个例子里是 (*),也就是乘积。xs 和 ys是两个集合(haskell里是List类型),zipWith将函数f应用在两个集合的对应元素上,并将结果组成另一个集合作为结果。
sum函数将集合的每个元素进行累加。
所以这段代码的意思就是把集合xs和ys的对应元素乘起来,然后将结果集合的每个元素累加起来。
haskell的代码就是这段代码所做的事的直观描述,一旦习惯了haskell的写法,就会发现haskell代码的可读性要好得多。

高阶函数(即可以接受函数作为参数)使程序的扩展性大增,
加入不想求乘积了,想求和怎么版呢?将(*)改成(+),这个是最简单的扩展。
假如你想把xs集合的每个元素与ys集合的每个元素做个比较,x>y大于则为True,否则false,要怎么实现呢?
(>)也是一个能接受两个参数,返回一个结果的函数哦!
isLarger :: [Int] -> [Int] -> [Bool]
isLarger xs ys = zipWith (>) xs ys
 
正如 why functional programming matters 论文中所说的,函数式编程给语言加入了一个重要的“胶水机制“--高阶函数,可以用来将小块的功能块组合为大的功能块。这个机制是非常有价值的。

你可能感兴趣的:(编程,C++,c,C#,haskell)