第一个函数
创建doubleMe.hs文件,编写如下代码:
代码语言:javascript复制doubleMe x = x x
保存,打开ghci,输入
代码语言:javascript复制Prelude> :l doubleMe.hs
这样我们就加载了我们的doubleMe函数,然后就可以调用这个函数:
代码语言:javascript复制Prelude> doubleMe 10
20
tip: 如果修改doubleMe.hs文件需要重新导入的话可以执行:reload doubleMe.hs或者:r doubleMe.hs重新导入
if语句
Haskell中的if语句与其他语言不同,else是不可以省略的
代码语言:javascript复制doubleSmallNum x = if x > 10 then x else x * 2
Haskell 中的 if 语句的另一个特点就是它其实是个表达式,表达式就是返回一个值的一段代码:5 是个表达式,它返回 5;4 8 是个表达式;x y 也是个表达式,它返回 x y 的结果。正由于 else 是强制的,if 语句一定会返回某个值,所以说 if 语句也是个表达式。
List
列表由方括号以及被逗号间隔的元素组成:
代码语言:javascript复制Prelude> [1,2,3]
[1,2,3]
空列表:[],列表中所有元素必须是同一类型。
列表操作符
用 操作符连接两个list
代码语言:javascript复制Prelude> [1,2,3] [4,5,6]
[1,2,3,4,5,6]
用 : 连接一个元素到list头,它读作“cons”即construct简称
代码语言:javascript复制Prelude> 1:[2,3]
[1,2,3]
但是[2,3]:1是不被允许的,因为:的第一个参数必须是单个元素,第二个参数必须是list
字符与字符串
代码语言:javascript复制Prelude> "this is string"
this is string
双引号表示字符串。单个字符用”表示
代码语言:javascript复制Prelude> 't'
t
字符串实际是字符列表,
代码语言:javascript复制Prelude> 't' : "his is string"
this is string
Prelude> "this is" " string"
this is string
操作
从list中取值使用!!(相当于其他语言中的arr[index])
代码语言:javascript复制Prelude> let l = [1,2,3]
Prelude> l!!1
2
上面的例子就是从列表l中取下标为1的元素 list可以用来装list:
代码语言:javascript复制Prelude> let l = [[1,2,3], [1,2,3,4], [1,2,3,4,5]]
haskell不要求每个元素的长度一致,但要求类型必须一致
- head函数取list第一个元素
- tail函数取list除第一个元素之后的全部
- last返回list最后一个元素
- init返回一个除去list最后一个元素的全部
- length返回list长度
- null判断list是否为空,如果是空返回True,否则False
- reverse 反转list
- take 返回前几个元素
- maximum 返回最大元素
- minimun 返回最小元素
- sum 返回所有元素之和,product返回积
- elem 判断一个元素是否存在于list中,通常中缀调用
Prelude> tail [[1,2,3], [1,2,3,4], [1,2,3,4,5]] [[1,2,3,4], [1,2,3,4,5]] Prelude> init [[1,2,3], [1,2,3,4], [1,2,3,4,5]] [[1,2,3], [1,2,3,4]] Prelude> reverse [1,2,3] [3,2,1] Prelude> take 2 [1,2,3] [1,2] Prelude> 1 `elem` [1,2,3] True
Range
可以用列表符号来表示一系列元素,haskell会自动推导:
代码语言:javascript复制Prelude> [1..10]
[1,2,3,4,5,6,7,8,9,10]
Prelude> [1.0, 1.25, ..2.0]
[1.0,1.25,1.5,1.75,2.0]
Prelude> [1, 4, 15]
[1, 4, 7, 10, 13]
之所以没有输出15是因为15不属于我们定义的系列元素
List Comprehension
代码语言:javascript复制Prelude> [x*2 | x <- [1...10]]
[2,4,6,8,10,12,14,16,18,20]
可以给这个comprehension加个限制条件:
代码语言:javascript复制Prelude> [x*2 | x <- [1...10], x*2 > 12]
[14,16,18,20]
下面写一个函数,该函数使list中所有>10的奇数变为”BANG”,小于10的奇数变为BOOM:
代码语言:javascript复制bangBoom xs = [if x > 10 then "BANG" else "BOOM" | x <- xs, odd x]
tip: odd函数判读x是否是奇数,如果是则返回True
还可以从多个list中取元素:
代码语言:javascript复制[x*y | x <- [1,2,3], y <- [4,5,6]]
[4,5,6,8,10,12,12,15,18]
实现自己的length函数:
代码语言:javascript复制length' xs = sum [1 | _ <- xs]
_表示我们不会用到这个值 操作含有 List 的 List
代码语言:javascript复制Prelude> let xxs = [[1,3,5,2,3,1,2,4,5],[1,2,3,4,5,6,7,8,9],[1,2,4,2,1,6,3,1,3,2,3,6]]
Prelude> [ [ x | x <- xs, even x ] | xs <- xxs]
[[2,2,4],[2,4,6,8],[2,4,2,6,2,6]]
Tuple
代码语言:javascript复制(1,2) (True, "a", 1)
Tuple List:
代码语言:javascript复制[(1,2),(3,4),(5,6)]
但是[(1,2),(3,4,5),(5,6)]
是会报错的,因为元素类型不一致
两个元素的Tuple可以称为序对(Pair) Tuple不能是单元素的,因为没有意义
操作函数
fst 返回序对的首项(只能操作序对,不能操作三元组等其他数量的Tuple)
snd 返回序对的尾项
代码语言:javascript复制Prudule> fst (1,2,[1,2,3])
1
Prudule> snd (1,2,[1,2,3])
[1,2,3]
zip 将两个list交叉配对生成一组Pair
代码语言:javascript复制Prudule> zip [1 .. 5] ["one", "two", "three", "four", "five"]
[(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five")]
Prudule> zip [5,3,2,6,2,7,2,5,4,6,6] ["im","a","turtle"]
[(5,"im"),(3,"a"),(2,"turtle")]
若是两个不同长度的 List,较长的那个会在中间断开,去匹配较短的那个