use*_*317 4 haskell function clause pattern-matching compiler-warnings
这是我的代码:
tell :: (Show a) => [a] -> String
tell [] = "The list is empty"
tell (x:[]) = "The list has one element: " ++ show x
tell (x:y:[]) = "The list has two elements: " ++ show x ++ " and " ++ show y
tell (x:y:_) = "Other"
Run Code Online (Sandbox Code Playgroud)
在最后一行中,为什么不能更改(x:y:_)为[x, y, _]?
全局含义是_什么?
bra*_*drn 13
在最后一行中,为什么我不能将(x:y:_)更改为[x,y,_]
它们具有不同的含义:
[x, y, _] refers to a list with three elements; the first element is bound to x, the second is bound to y, and the third element is not bound to any name. It's equivalent to (x:y:_:[]).(x:y:_) refers to a list with at least two elements, since : is a constructor used to join the first element of a list with the rest of the list; in the above pattern, the first element is bound to x, the second is bound to y, and the rest of the list (which may or may not be empty) is not bound to any name.And what the global meaning of _?
您实际上不应该在一个帖子中问两个问题,但这在这里很重要,因此:_当您想匹配特定模式但不给它命名时,它只是一个占位符。所以在上面的例子中:
[x,y,z]将三元素列表的每个元素结合的名称x,y和z分别(完全等价(x:y:z:[]))。当您更换z使用_,但它仍然匹配的三个元素的列表,但并没有给最后一个元素的名称。(x:y:z)将一个在-至少-两个元素的列表的前两个元素结合的名称x和y,然后结合该列表的其余部分z。当您更换z使用_,它仍然符合至少两个元素的列表,但不给列表的其余部分的名称。mel*_*ene 10
您可以更改(x : y : _)为[x, y, _],但这并不意味着同一件事。[x, y, _]等价于(x : y : _ : []),即正好包含三个元素的列表(其中前两个元素绑定到x和y)。
同样,x : y是一个列表,其头(第一个元素)为x,而尾部(其余元素)为y,但[x, y]正好是两个元素的列表。
我不确定您所说的“全局含义” _是什么,但是它是一个通配符模式,可以匹配任何值,但不会将其绑定到名称。