发布在即!企业 AIGC 应用程度测评,3 步定制专属评估报告。抢首批测评权益>>> 了解详情
写点什么

专访《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:575522
用户头像
臧秀涛 略懂技术的运营同学。

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

关注

评论

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

kubernetes GPU的困境和破局

琦彦

人工智能 机器学习 gpu Kubernetes

简化理解:发布订阅

掘金安东尼

前端 设计模式 7月月更

React 学习记录📝

程序员海军

React 7月月更

Getaverse,走向Web3的远方桥梁

股市老人

【函数式编程实战】(五) Stream实战大全

小明Java问道之路

java8 函数式编程 实战 Stream API 7月月更

Kubectl_好用的命令行工具:oh-my-zsh_技巧和窍门

琦彦

Shell kubectl Oh My Zsh zsh

做完数据治理,质量依旧很差

奔向架构师

数据治理 7月月更

期盼已久全平台支持-开源IM项目OpenIM之uniapp更新

Geek_1ef48b

Getaverse,走向Web3的远方桥梁

EOSdreamer111

我们为什么要推出Getaverse?

BlockChain先知

微信朋友圈的高性能复杂度分析

gump

架构实战营

程序员都应该知道的 21 个 Git 命令

yuexin_tech

git

Go小白实现一个简易的go mock server

真嗣

golang

python小知识-命令行参数处理之argparse

AIWeker

Python python小知识 7月月更

5年接触近百位老板,身为猎头的我,发现升职的秘密不过4个字

图灵教育

茅台冰淇淋“逆势”走红,跨界之意却并不在“卖雪糕”

易观分析

茅台

kubernetes多网卡方案之Multus_CNI部署和基本使用

琦彦

Kubernetes cni 多网卡 multus

工程项目管理软件排名

PingCode

项目管理 项目管理软件

2022年IAA行业品类发展洞察系列报告·第二期

易观分析

IAA

Kubernetes版本对接对象存储

琦彦

对象存储 pvc

邻接表的定义和存储以及有向图无向图的邻接存储

乔乔

7月月更

C# 窗体应用TreeView控件使用

IC00

C# 7月月更

Docker部署Springboot项目

宁在春

Docker springboot 7月月更

基于GitHub/七牛云 + PicGo 搭建属于Typora的图床

琦彦

GitHub Typora PicGo 图床

Getaverse,走向Web3的远方桥梁

鳄鱼视界

贪心算法:用最少数量的箭引爆气球 🎈

空城机

算法题 7月月更

Istio1.12:安装和快速入门

琦彦

istio Sidecar 流量管理

iptables常用命令小清单

琦彦

Linux 网络 iptables

利用Python手把手带上实现冒泡排序

迷彩

算法 排序算法 7月月更 算法优化

【刷题记录】20. 有效的括号

WangNing

7月月更

JVM方法调用

技术小生

JVM 7月月更

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