Haskell 学习笔记一:基础
这是一个新的系列,主要讲讲我在学习 Haskell 的过程中遇到的一些坑和心得,希望能用最简单的语言给初学者提供一些帮助。整个系列预计会有三到四篇博文。主要会包含:
- Basics
- 数据类型
- Functors, Applicatives, Monads
- State
- Parser
- Interpreter
会写这个系列的原因是因为在初期我学得实在是太痛苦了,但是入门之后被深深折服,Haskell 实在是太优雅了。
Haskell 实在是是一门无比优雅且深奥的语言。才疏学浅[1],只能窥得冰山一角,权当抛砖引玉。
在写作过程中有参考多伦多大学 Albert Lai 教授的课程设计。
希望能给中文世界的各位一些帮助。
这玩意在工业界流行不起来是有理由的,再牛逼也得有人学并且学得会是不是
Eva-00
this should be in ayanami blue
Haskell 是一门函数式编程(functional programming, FP)语言。和我们最常接触的面向过程(procedural programming)和面向对象(object oriented programming, OOP)不同,函数式编程更像数学上的函数。一个显著的差别是 Haskell 几乎没有变量(其实是有的,但是我们先放在一边,因为确实和你想的不太一样)。对于习惯了 C 之类的我们来讲,学起来确实还是相当痛苦的。
我不打算覆盖很多的基础内容,互联网上有很多比我写得更好的资源。不过如果有需求的话可以加上一些。这个系列的主要目的是写写我在学习过程中遇到的难点。
国际惯例,先来一发 Hello World
main :: IO ()
main = putStrLn "Hello, World!"
函数
Haskell 的函数非常类似数学上的函数。
factorial :: Integer -> Integer
factorial 0 = 1
factorial n = n * factorial (n - 1)
这是一个很简单的 factorial 函数。意思是给一个数,输出这个数的阶乘。
第一行:类型签名(type signature),输入一个整数,输出一个整数
二到三行:pattern matching(模式匹配?不知道正式翻译是啥)。这是非常有意思的地方。
第二行:如果输入是 0,则输出 1
第三行:如果不是,就递归输出它的结果(n*factorial(n-1))。
在 Haskell 里,执行函数会从前往后匹配,并且执行匹配到的区块。
调用它的方法也和其他的语言很不同,直接函数名+空格+输入,比如 factorial 0
同样的,如果有一个函数是这样的:
add2 :: Integer -> Integer -> Integer
add2 x y = x + y
add2
则接受两个 Integer 类型的输入,有一个 Integer 类型的输出。
但是魔法来了。如果只给 add2
提供了一个参数呢?
Integer -> Integer -> Integer
事实上和 Integer -> (Integer -> Integer)
是一样的,即 add2 函数收到第一个 integer 输入的时候返回的是另一个类型是 Integer -> Integer
的函数,第二个输入则被提供给这个函数。
举个例子,(add2 0)
,返回的就是一个类型为 Integer -> Integer
的函数。(add2 0) 1
则把 1
作为输入提供给了 (add2 0)
返回的函数,得到我们想要的结果。(add2 0) 1
和 add2 0 1
是一样的。
今天先到这里。
真的不是谦虚 ↩︎