haskell 如何以 head 函数的模式打破列表

问题描述

在学习 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

headtail 指针未初始化,因为它们未被使用。当您编写 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 = 1xs = [2,3]

所以这里没有“落后”“爆炸”,不会破坏

每个 : 都有 两个 字段。就是这样。