尝试在Haskell中理解一些奇怪的符号,如([]:_)

时间:2015-12-30 20:45:49

标签: list haskell pattern-matching

我很难理解以下Haskell符号([]:_)

我遇到了一个名为transpose的Haskell函数

transpose::[[Int]]->[[Int]]
transpose ([]:_) = []
transpose  x = (map head x):transpose(map tail x)

我将介绍一个简单的例子。

transpose [[1,2],[3,4]]
=>[1,3]:transpose[2,4]
=>[1,3]:[2,4]:transpose[[],[]]
=>[1,3]:[2,4]:[]
=>[[1,3],[2,4]]

似乎有道理。

但如果我将[[], [1]]传递给该函数,则输出仍为[]

transpose [[], [1]]
=>[]

如果我通过[]

,有人可以解释为什么转置返回[[], [1]]

2 个答案:

答案 0 :(得分:4)

这不是符号([]:_)只是简短版本:

( [] : _ )
^  ^   ^
|  |   wildcard
|  empty list
list construct

列表构造类似于( h :t ),其中h是头部(元素),尾部是t(列表的其余部分或空列表)。有关详细信息,请参阅CONS

所以这意味着:匹配一个列表作为空白列表的头部,并作为尾部匹配不关心

这是有道理的,因为转置仅在矩形结构上很好地定义。您期望[[],[1]]的转置应该是什么。

这一行必要的原因是因为在第二次(递归)调用中,您使用了所有列表中的tail

如果你这样计算[[1,2,3],[4,5,6],[7,8,9]]的转置,你将首先采用递归的情况:作为head,你发出所有列表的所有头部,所以[1,4,7]和使用所有列表中的tail来完成递归,因此您可以使用transpose [[2,3],[5,6],[8,9]]调用它。

在第二轮(递归调用)中,您再次发出列表的head,所以[2,5,8]并在tail上执行递归调用:{{1} }。接下来,您再次发出[[3],[6],[9]] s head,现在[3,6,9]上的递归调用是tail。所以列出所有空列表。但是,如果矩阵条件成立,则意味着我们已经完成了。模式transpose [[],[],[]]( [] : _)匹配,因此它将发出空列表[[],[],[]]

答案 1 :(得分:0)

这不是一个矩阵!您的第一行为空,因此满足第一个条件并返回定义的空列表。