写点什么

专访《Haskell 函数式编程入门》作者张淞:浅谈 Haskell 的优点与启发

  • 2015-08-20
  • 本文字数:3448 字

    阅读完需:约 11 分钟

张淞,Haskell 语言爱好者,著有《Haskell 函数式编程入门》一书。目前就职于网易杭州研究院。在10 月15 日~17 日的 QCon 上海 2015 上,他将分享《Haskell 中的函数与类型系统》

Haskell 中的主要概念其实都是围绕类型展开的,类型系统主要是为我们管理程序的抽象与保证程序的正确性而引入的。为了更好的复用代码,于是有了多态类型。某些类型有着共同的属性,于是 Haskell 引入了类型类来管理它们。有一些类型是需要接受一个或者多个类型参数的,为了保证这一环节不会出错,于是 Haskell 又引入了 kind 这一概念;同样出于复用代码的原因,Haskell 又引入了 kind 多态。总之,抽象在一步一步加深,每加深一步就总结出更多公共的代码,为我们自动完成更多事情,而带来的问题就是会让人更加难以理解。所以了解 Haskell 的类型系统对于我们理解代码的复用、抽象非常有帮助。所以本次的演讲主要包括:

  • Haskell 中的值
  • Haskell 中的类型
  • Haskell 中的类型类
  • Haskell 中的类型的 kind
  • 以上特性之应用

Haskell 不仅仅是一门学术型的语言,而是一门非常适用于编写应用软件的工程型语言,其实相当多的思想是可以迁移到非函数式语言上的,但是对想要应用这些思想的人来说,在思维的转变上可能会有更长的路要走。主要的问题是,现在的人们习惯于他们已经熟悉的东西,需要学习如何让函数编程中的理论来指导实践编程,最大程度上减少重复,用更少的代码完成更多的工作。

在大会开始前,InfoQ 采访了张淞,谈到了 Haskell 的优点,对实际编程的启发等话题。以下为采访内容:

InfoQ:您好,可以简单做一下自我介绍吗?

张淞:我本名叫张淞 ,网上叫阅千人而惜知己,算是一个文艺屌丝吧。2012 年从英国诺丁汉大学本科毕业,2013 年从牛津大学研究生毕业,都是计算机科学专业。课程并没有特别明确的方向,但是由于偏爱函数式编程与编程语言一些,所以选课大多与之相关。2014 年年初,因为母校宁波诺丁汉大学空缺一个临时的教职,于是牛津大学毕业后就先决定回国任教了,全职教授函数式编程这门课,所用的语言就是 Haskell。目前供职于网易杭州研究院,现在的工作与数据分析相关。

InfoQ:从学校到公司应该有很多不同,可以分享一下这方面的感受么?

张淞:在学校工作时我没有研究压力,所以是比较自由的。在教函数式编程之前,这门课的课本我已经读了 5 遍,并且已经译成中文。书很薄,是由我在英国诺丁汉大学的老师 Graham Hutton 教授著的。后来在牛津又旁听了一遍这门课,当时还给有问题的同学答疑,所以回到宁波诺丁汉大学,教大二的学弟学妹们基本上是驾轻就熟的。教学任务也不是很大,一周大约有 2 小时的教学还有 2 小时的研讨课,课件、课本、练习、试卷的参考很多,也不用太花时间准备,所以比较轻松。有时间可以做自己喜欢的事,从 SICP 那本书上找一些题出给学生,读一些 Haskell 相关的论文。而在公司则不太一样,但是在网易杭州研究院,好处就是我们的工作不太会受到技术的限制,完全是由我们做什么、想怎么做决定的,不单调也不乏味,但只是感觉在公司的工作压力比较大,因为自己的工作关乎到其他同事的进度,但即便如此还是比较开心,因为还在做着自己喜欢的事。

InfoQ:Haskell 吸引你的地方是?

张淞:严格地说我的第一语言是 Java,教我学 Haskell 的人正是招我回去教书的那位老师。很坦诚地讲,Haskell 在一开始并不吸引我,纯函数、没有变量让当时的我十分困惑并且有点抵触。后来考试完,在学校的图书馆里解了 24 点,发现用 Haskell 比同学的 Java 解法长度短了接近 10 倍,后来又解决了八皇后问题,也是比 Java 少了近 10 倍的代码;先不说效率,单纯在表达能力上,Haskell 是不能与其他如 Java 一类的语言同日而语的。偶然间又在学校图书馆里发现了 Real World Haskell,完全颠覆了我对 Haskell 肤浅的认识,才知道那薄薄的课本连 Haskell 的冰山一角都不算。

Haskell 吸引我的地方主要是,强大的类型系统十分严谨,部分地方严谨到让人“发指”。这里可以举一个例子,3.14 是小数,3.14e3 等于 3140,而 3140 可以当成数字来处理,因为它可以是整数,也可以是小数,所以应该归属于一个更为一般的类型类 Num 而不是 Integral 或者 Fractional:

复制代码
> :t 3.14
3.14 :: Fractional a => a
Prelude> :t 3.14e3
3.14e3 :: Fractional a => a
Prelude> :set -XNumDecimals // 开启语言扩展
Prelude> :t 3.14e3
3.14e3 :: Num a => a

我没有看到任何语言注意到了这种类型上的微妙变化,Clojure 里直接就是 Double 了。Haskell 里数字类型与数字类型类的关系是相当严谨的,严谨到如果没有一定的理论背景根本不会清楚它背后这么设计的原因,Haskell 里有很多不断颠覆我之前思想的设计。有这样细致入微的类型系统辅助可以保证很大一部分错误不会出现,因为根本写不出来不满足类型的代码,并且在我们的头脑并不清醒的时候编译器会始终帮助你保持理智。

另外,Haskell 的基础 API 设计非常有条理,这也是一些语言比如 Scala 的 scalaz、JavaScript 的 Prelude.ls、Ix,基本都是基于 Haskell Prelude 的。Github 上的 CoffeeScript 的 coffee-mate 与 lazy.coffee,C++ 基于 boost 的 prelude_CPP 都或多或少受了 Haskell 的 API 设计的影响,你可以在 Github 上找到很多这样模仿 Haskell Prelude 的项目。

InfoQ:您感觉 Haskell 主要适合哪类项目?您在工作中使用多吗?

张淞:我并没有什么特别大的项目经验,只是在学校里做过几个玩具级别的编译器与解释器,另外还有一些其他小玩具,不能拿出见人的。但我能比较确定的是,用 Haskell 来编写其他语言的编译器与解释器肯定再合适不过了,整套流程我也比较清楚。恐怕最著名的例子可能就是唐凤的 Perl 6 实现—— Pugs 了,还有由 Ulf Norell 在博士期间用 Haskell 实现的依赖类型的编程语言—— Agda ,另外还有 Haskell 广泛使用的编译器 GHC ,从 92 年到现在已经 20 多年了,还是有非常好的可维护性并且在快速进化着,有很多教授与博士在这个平台上做研究,每次更新都有很多新的特性加入,一件事物有这种进化的能力其实是很可怕的,无论它刚问世的时候有什么缺陷。其实就我的所见所闻,Haskell 从前端到高性能服务器、再到嵌入式开发、自动交易系统都有比较成功能例子,所以 Haskell 比较适合做什么更多的是由人来决定的。

我在工作中直接使用 Haskell 的机会并不多,但是我会使用 Haskell 做一些原型设计与网络接口测试。主要用的还是 Haskell 中的一些思想,比如代数类型、尽量消除变量的共享、尽可能多地使用纯函数等等,此外如果要在动态类型与静态类型语言中做选择,我会主观地倾向于后者。

InfoQ:在实际的业务开发中,选择编程语言会考虑哪些因素?

张淞:我工程经验并不是很多,主要是考虑要解决的问题与团队吧。最近解决的问题比较特殊,所以老大决定用了 Clojure,因为需要用到一个很重要的库,只有 Clojure 的实现比较好,另外就是团队里的人多少都有一些函数式编程背景,所以最后决定使用了 Clojure。

InfoQ:在国外会有不少实际的项目会应用到 Haskell,比如近日 InfoQ 曾报道过 Facebook 如何使用 Haskell 处理垃圾邮件**。**就您所知,Haskell 在国内的应用情况如何?

张淞:我在 Haskell 的 QQ 群里得知有几个小的创业团队在用 Haskell 做前端开发还有游戏服务端开发,但是没有深入了解。在我看来,国内是没有什么使用函数式编程语言的氛围的。最近网易在招聘,看了很多份简历,基本没有见到有函数式编程语言背景的人,感觉主要的问题还是出在中国的高校,有函数式编程这门课的高校屈指可数,他们教的主要还是 C/C++、MFC 这些东西,懂的要么是一些感兴趣的学生,要么是一些好学的工程师,希望以后有空能以网易云课堂为平台进一步推广一下函数式编程。

InfoQ:如果实际应用比较少,您感觉 Haskell 能给我们实际编程带来哪些启发?

张淞:我在前面大约提了几点,一个是 Haskell 核心的 API 的设计逻辑十分清楚,所以被很多语言争相模仿。无论你用什么语言,在设计 API 的时候照着 Haskell 中 Functor、Applicative、Monad、Traversable、Foldable 这些类型类来实现你的 API,最后的逻辑条理都会非常清楚,基本不会看到眼花缭乱的设计模式满天飞,我在看其他语言的 API 的时候也会找它们在 Haskell 中的对应。在实践中很多事情是从零开始的,我一般是先会定义出全部我所需要的类型,然后把计算与程序运行的流程搞清楚,明确需要从哪些类型计算出哪些类型并把函数签名写下来,接下来开始实现他们,最后把它们组合起来得到最终完整的程序。

InfoQ:感谢接受我们的采访,期待您在 QCon 上的分享。

2015-08-20 22:575845
用户头像
臧秀涛 略懂技术的运营同学。

发布了 300 篇内容, 共 134.4 次阅读, 收获喜欢 35 次。

关注

评论

发布
暂无评论
发现更多内容

记一次HEX和RGB互换算法的思考及应用

徐小夕

Java 面试 算法 大前端

架构师训练营 - 第 9 周课后作业(1 期)

Pudding

软件测试系统学习流程和常见面试题

测试人生路

软件测试

LeetCode069-x的平方根-easy

书旅

数据结构 算法 Go 语言

Serverless 架构就不要服务器了?

华为云开发者联盟

云计算 Serverless 架构

披星戴月地辛苦割胶或成历史,海南胶园迎来这一“神器”!

华为云开发者联盟

云计算 大数据 IoT

阿里云原生中间件首次实现自研、开源、商用“三位一体”,技术飞轮效应显现

阿里巴巴云原生

阿里云 云原生 中间件

从基础设施到云原生应用,全方位解读阿里云原生新锐开源项目

阿里巴巴云原生

阿里云 开源 云原生

Minikube-运行在笔记本上的Kubernetes集群

网管

学习 Kubernetes k8s minikube k8s入门

第九周作业

智能灯串开发资料全开源!为这个冬天装点烂漫“星空”

智能物联实验室

人工智能 物联网 智能硬件 智能家居

架构训练营 - 第9周课后作业 - 学习总结

Pudding

第九周作业

Geek_4c1353

极客大学架构师训练营

0到1产品需求整理分析模型参考

燕陈华

产品设计 产品需求

详解企业管理系统工作流配置

Marilyn

敏捷开发 工作流 软件架构

《Elasticsearch服务器开发》.pdf

田维常

elasticsearch

排序与二分

落曦

华为云MVP付健权:从机械工程师到AI开发者的华丽转身

华为云开发者联盟

AI 转型 工程师

开发霸总:我要让所有人知道,这个扫码组件,被你承包了

蚂蚁集团移动开发平台 mPaaS

支付宝 uniapp mPaaS

Java程序员说:世界上有三个伟大的发明【火、轮子、kafka】

Java架构师迁哥

Istio 中的智能 DNS 代理功能

Jimmy Song

开源 云原生 Service Mesh istio 服务网格

除了类 Excel, SpreadJS 表格控件还能为系统开发带来什么价值?

葡萄城技术团队

为什么你的“开发速度”和“产品性能”,都比不过竞品?丨开发者必读

葡萄城技术团队

田哥:面试被问== 与equals 的区别,该怎么回答?

田维常

面试

“人上人”大专学历,通过系统的六个学习步骤,艰难4面终砍offer,“跳进”字节跳动

Java架构追梦

Java 架构 字节跳动 面试 微服务

云原生趋势下的迁移与容灾思考

阿里巴巴云原生

云原生 迁移 容灾

第九周课后练习

饭桶

第9周学习总结

饭桶

第九周总结

解读下一代网络:算力网络正从理想照进现实

华为云开发者联盟

AI 5G 网络 云技术

上线操作规范——基础版本

程序员架构进阶

团队管理 开发流程 发布流程 规范

专访《Haskell函数式编程入门》作者张淞:浅谈Haskell的优点与启发_后端_臧秀涛_InfoQ精选文章