问题描述
在学习 Haskell 时,我无法理解 Haskell 如何自动匹配提取列表头部的模式。
head' :: [a] -> a
head' [] = error "Can't find head in an Empty list!"
-- How does haskell break the list into x(first) and xs(rest)?
head' (x:xs) = x
我读过 [1,2,3]
是 1:2:3:[]
的语法糖。
那么 :
是一个接受任何参数并添加到右手参数的函数?
列表是如何向后分解成两个变量 head 和 rest 的?
[1,3] --> (x:xs)
??
colon_operator :: a -> [a]
-- not sure how the function would look
抱歉,如果我不能简明扼要地解释我的问题,我不太擅长 Haskell。
解决方法
告诫讲师:这是第零个近似值,在很多方面都是错误的,但至少它是第零个近似值!
使用伪代码,当您调用 []
或 :
时,会创建一个新的数据结构。以下是使用命令式语言编写结构的方法:
structure {
int constructor
ptr head
ptr tail
} list
当您编写 empty = []
时,它会分配一个新的 list
,并以这种方式填充它:
empty = alloc(list)
empty.constructor = 0 // 0 means we used [] to construct this
head
和 tail
指针未初始化,因为它们未被使用。当您编写 not_empty = 3 : [4]
时,它会分配一个新的 list
,并以这种方式填充它:
// three is a pointer to 3
// four is a pointer to [4]
not_empty = alloc(list)
not_empty.constructor = 1 // 1 means we used : to construct this
not_empty.head = three
not_empty.tail = four
现在,当您对列表进行模式匹配时,这相当于检查 constructor
字段。所以如果你写,说:
case not_empty of
[] -> 7
x:xs -> 20 + x
那么命令式发生的事情是这样的:
if not_empty.constructor == 0
return 7
elseif not_empty.constructor == 1
return 20 + dereference(not_empty.head)
endif
(同样,如果您提到了 xs
,它会取消引用 tail
指针。)
在构建 list
结构和对它们进行模式匹配之间,您现在知道用于构建列表上每个函数的基本构建块!在最基本的层面上,这是您唯一可以做的两件 list
-y 事情。
[1,2,3]
是 1:[2,3]
的语法糖,即 ...
... (x:xs)
其中 x = 1
和 xs = [2,3]
。
所以这里没有“落后”“爆炸”,不会破坏。
每个 :
都有 两个 字段。就是这样。