Chapter 2. Types and Functions
Why Care About Types?
略
Haskell’s Type System
Haskell 的类型是静态,强类型,能够自动推断。
Static Types
静态类型的意思是编译器在编译时知道所有值和表达式的类型。
静态强类型保证Haskell 在运行时不可能出现类型错误。
What to Expect from the Type System
略
Some Common Basic Types
Char 值
表示Unicode 字符
Bool 值
True, False
Int 类型
用于有符号,固定宽度值。宽度决定于机器字长,如32 位,64 位等。Haskell 保证Int 不小于28 bits。
Integer 值
Integer 不如Int 常用,因为性能和空间开销大。Integer 不会不声不响的溢出。
Double
double 通常是64 位,不推荐使用float,因为float 性能不高。
定义变量类型的运算符“::”
'a' :: Char
:type 'a' --> 'a' :: Char
格式是:变量+“::”+ 类型签名
Function Application
调用函数的方法
odd 3 --> True
odd 6 --> False
compare 2 3 --> LT
compare 3 3 --> EQ
compare 3 2 --> GT
(compare 2 3) == LT --> True
compare (sqrt 3) (sqrt 6) --> LT
Useful Composite Data Types: Lists and Tuples
tuple 是固定大小,可以装不同类型的元素。
tuple 一般只用来存不多的几个元素。
tuple 通常作为返回多个值的函数的返回值。
tuple 的写法
(1964, "Labyrinths")
使用head 函数获取list的第一个元素
head [1,2,3,4] --> [2,3,4]
使用tail 函数获取list的第一个元素后面的所有元素
tail [True,False] --> [False]
“[a]”表示类型为a 的列表
list 是多态的,可以存放任意类型的值,[a] 中的a 是一个占位符
:type [[True],[False,False]] --> [[True],[False,False]] :: [[Bool]]
Functions over Lists and Tuples
take函数获取list 的前n 个元素
take 2 [1,2,3,4,5] --> [1,2]
drop 函数移除list 的前n 个元素
drop 3 [1,2,3,4,5] --> [4,5]
获取tuple(pair tuple) 的第一或第二个元素
fst (1,'a')
snd (1,'a')
注意,这两函数只对含两个元素的tuple 有效
Function Types and Purity
使用lines 函数分割串
lines "the quick/nbrown fox/njumps"
--> ["the quick","brown fox","jumps"]
没有side effects 的函数是纯函数,有side effects 的是非纯函数。
有side effects 的函数的签名带有IO 标记
:type readFile
--> readFile :: FilePath -> IO String
Haskell 的类型系统会阻止混用纯和非纯函数。
Haskell Source Files, and Writing Simple Functions
ghci 的操作环境称为IO monad
定义函数的方法
-- file: ch03/add.hs
add a b = a + b
:load c:/add.hs
add 1 2 --> 3
用cd 命令改变ghci 的工作目录
:cd c:/
:load add.hs
add 1 2 --> 3
Just What Is a Variable, Anyway?
变量一旦赋值就不能再改变
x = 10
x = 11 -- 错误
变量是表达式的替代品
Conditional Evaluation
条件语句
-- myDrop.hs
myDrop n xs = if n <= 0 || null xs
then xs
else myDrop (n - 1) (tail xs)
:load myDrop.hs
myDrop 2 "foobar"
"obar"
“xs”中的“s”表示复数字尾。参数n 决定了递归调用的次数,既将一个列表tail 多少次。
逻辑或运算符“||”不是语言内置的,只是一个普通函数
Understanding Evaluation by Example
Lazy Evaluation
测试一个数是不是偶数
isOdd n = mod n 2 == 1
isOdd (1 + 2)
传参的时侯 (1+2) 不会先计算出结果3 然后再传给isOdd 函数。
发生的事情是:创建一个thunk (表达式的引用) 传给函数,并延迟计算表达式的结果。如果一直用不到那个结果就永运不会计算它。
Polymorphism in Haskell
返回列表的最后一个元素
last [1,2,3,4,5] --> 5
The Type of a Function of More Than One Argument
“->” 的读法
:type take
take :: Int -> [a] -> [a]
“take :: Int -> [a] -> [a]”是右结合的,相当于“take :: Int -> ([a] -> [a])”,接受一个参数int,返回另一个函数。
“->”的前面是函数的参数,后面是函数的返回值。
定义函数的类型签名
-- add.hs
add a = a + 1
add :: Int -> Int