我很难理解以下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]]
答案 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)
这不是一个矩阵!您的第一行为空,因此满足第一个条件并返回定义的空列表。