类型 [a] -> [a] -> [a]
Haskell 中使用 ++
进行两个同类型的表列增加,e.g.
ghci> let x = [1, 2, 3]
ghci> let y = [4, 5, 6]
ghci> x ++ y
[1,2,3,4,5,6]
类型 a -> [a] -> [a]
Haskell 使用 :
将左侧的Operand添加到右侧的Operand上:
ghci> let x = [1, 2, 3]
ghci> 0 : x
[0,1,2,3]
类型 [a] -> Int
ghci> let x = [1, 2, 3]
ghci> length x
3
类型 Int -> [a] -> [a]
ghci> let x = [1, 2, 3]
ghci> take 2 x
[1,2]
ghci> take 5 x -- 取出的 n 大于数组的长度
[1,2,3]
类型 [a] -> Int
ghci> let x = [1, 2, 3]
ghci> head x
1
ghci> let y = [] -- 如果为空情况
ghci> head y
*** Exception: Prelude.head: empty list
类型 [a] -> [a]
ghci> let x = [1, 2, 3]
ghci> tail x
[2,3]
ghci> let y = [] -- 如果为空情况
ghci> tail y
*** Exception: Prelude.head: empty list
类型 [a] -> Int -> a
ghci> let x = [1, 2, 3]
ghci> x !! 2 -- 获取索引为2的,即x[2]
3
ghci> x !! 99 -- Out of Index
*** Exception: Prelude.!!: index too large
Haskell 是一门非常🐂的语言,其支持数组的惰性求值。简单来说, 对于一个长度为 n 的数组,如果我们只需要操作前 m 个元素,那么 后面的 n - m 个元素 Haskell 会默认不执行求值。正因为此特性, Haskell 支持了无穷数组(Infinite List)。
为了验证其,我们可以编写函数 from
,其类型为 Int -> [Int]
,
来返回一个从输入开始一直到无穷的函数
-- 位于 src/4-from.hs
-- ghci src/4-from.hs 可以自动装载此程序
from :: Int -> [Int]
from x = x : from (x + 1)
如果我们直接运行 from 1
,终端会输出 [1,2,3,4,5,6,7,8,9,10,...
并且不会停止,其表示了这个数组极度的长以至于很难一次性打印完。
但是如果我们执行 take 3 (from 1)
, 也就是我们从 [1,2,3,4,5,6,7,8,9,10,...
这个数组取出前3个,结果非常Amazing啊,Haskell并没有对整个数组执行
求值,而是只求了其中前三位(因为返回速度真的很快!)
ghci> take 3 (from 1)
[1,2,3]
还记得上面实现的 from
函数吗?其实使用Haskell自己的生成器就好了!
ghci> [1..5]
[1,2,3,4,5]
ghci> [1,3..9]
[1,3,5,7,9]
ghci> [1,3..10]
[1,3,5,7,9]
ghci> [1..]
[1,2,3,4,5,6,7,8,...
需要注意的是这个生成器对于小数是非常危险的,因为Haskell使用的是浮点数,存在精度问题,可以通过下列例子发现问题
ghci> [1, 1.25..5] -- Ok
[1.0,1.25,1.5,1.75,2.0,2.25,2.5,2.75,3.0,3.25,3.5,3.75,4.0,4.25,4.5,4.75,5.0]
ghci> [1, 1.33..5] -- Accuracy Issue
[1.0,1.33,1.6600000000000001,1.9900000000000002,2.3200000000000003,2.6500000000000004,2.9800000000000004,3.3100000000000005,3.6400000000000006,3.9700000000000006,4.300000000000001,4.630000000000001,4.960000000000001]
列表的本质是一坨元素的混合,例如[1,2,3]
,其本质是
1 : (2 : (3 : []))