设为首页收藏本站

LUPA开源社区

 找回密码
 注册
文章 帖子 博客

为什么我们要学习Haskell这样的编程语言

2012-4-11 09:46| 发布者: 红黑魂| 查看: 10273| 评论: 1|来自: 外刊IT评论

摘要: 最近的几个月,我一直在学习一种叫Haskell的编程语言。由于里面有太多的从未遇到的编程概念,整个过程就像是完全重新学习如何编程。在i.TV网站上,我写了很多JavaScript(node.js和前端代码)。虽然有不少的函数式/has ...

函数组合

在之前的例子中,我们遍历了数组两次,一次用来获取users,一次为了获取names。如果能在一次map映射操作中同时做这两件事情,效率会高很多。

function friendsNames(usersById, user) {
    return user.friendIds.map(function(id) {
        var friend = lookup(usersById, id)
        return lookup(friend, "name")
    })
}

我们得到首次lookup的结果,把它第二次传入lookup函数组合意思是串联多个函数,组成一个新的函数,每一次串联都是把前一个函数的输出当作下一个函数的输入。

让我们来写一个能这样运转的高阶函数,利用它把friendsNames函数重写成一个只需要单次map操作的函数。需要注意的是,函数串联的执行顺序是从右到左的,就跟你写出f(g(x))这样的代码的运行方式一样。

function compose(f, g) {
    return function(x) {
        return f(g(x))
    }
}

function friendsNames(usersById, user) {
    return user.friendIds.map(compose(applyr(lookup, "name"), apply(lookup, usersById)))
}

对数组的遍历只进行了一次,只使用一次map操作,跟我们头一个例子一样。

我们不能使用我们写出的friends函数,因为它既包含了如何取出一个friend的业务逻辑,也包含了map操作。friends函数是不能复用的,它的职责太多了——它是针对特定事物的。如果你们再写一个friend函数,让它只map一个friend,写一个name函数,让它返回对象的名称呢?

var friend = lookup // lookup 恰巧能干我们想要的事情。
var name = applyr(lookup, "name")

function friendsNames(usersById, user) {
    // this line is now more semantic. 
    return user.friends.map(compose(name, apply(friend, usersById)))
}

相较于定义一个既包含转换操作,又包含遍历操作的friends函数,我们只定义了一个可做转换操作的friend函数,而我们已经有了map函数为我做变换操作。friend函数比friends函数更具复用性,因为它包含更少的特定业务逻辑,能在更多的情形中使用。

这里你能找到更多的关于JavaScript里函数组合的信息。

函数式和功能单一化让你的代码库更整洁

我发现我的很多的JavaScript代码都是从无到有自己写出来的。这不仅仅是说比起使用现成的程序包要效率低,它还会暗藏更多的bug,更难阅读和维护。使用高阶函数和偏函数用法,我们可以写出可复用的程序库,每个函数都精准的对应解决它们能解决的一部分问题。

随着时间的推移,项目会变得越来越复杂,各部分越来越耦合,如果我们拥有的是一个能够各自独立测试不依赖的程序库,我们的项目会从中受益,变得更健康,更稳定。

  1. 一种宽泛的组合。并不特指函数或对象组合,只是一种你用小东西组建大东西的思想。

  2. “Matching functions”被称作predicates,但我这里不想引入新的编程术语。

  3. 这里有更通用的apply实现。

[本文英文原文链接:Learn You a Haskell: For Great Good? ]


酷毙
2

雷人

鲜花
1

鸡蛋

漂亮

刚表态过的朋友 (3 人)

  • 快毕业了,没工作经验,
    找份工作好难啊?
    赶紧去人才芯片公司磨练吧!!

最新评论

关于LUPA|人才芯片工程|人才招聘|LUPA认证|LUPA教育|LUPA开源社区 ( 浙B2-20090187 浙公网安备 33010602006705号   

返回顶部