1

假设我们在参数中有一个列表,并且在其头部和尾部分别匹配模式,所以我们使用x:xs. 这意味着输入被分成一个值x和一个列表xs

因此,冒号之前的任何内容都被视为单个值,而冒号表示法中的最后一个内容将是列表的其余部分,x删除了单个值。

但是,如果我想将最后一个值与其余值分开怎么办?似乎不能使用这种表示法。

更新:我想我知道如何使用递归找到最后一个数字,但是你不能简单地通过某种模式匹配得到它,这是真的吗?

4

2 回答 2

2

Haskell 数据类型[a]将列表表示为单链 cons 列表:模式匹配x:xs不仅仅是符号,而是它在内存中的存储方式,作为 head 和其余部分的 cons。

正如您在更新中提到的,您可以编写一个函数,该函数遍历一个列表并将其拆分为一个 init 部分和一个最后一个元素:

unsnoc :: [a] -> Maybe ([a], a)

您可以使用视图模式在模式匹配中使用它:

f (unsnoc -> Just (xs, x)) = ...
f [] = ...

您甚至可以将其包装成模式同义词

pattern xs :> x <- (unsnoc -> Just (xs, x))

(或双向版本

pattern xs :> x <- (unsnoc -> Just (xs, x)) where
  xs :> x = xs ++ [x]

)

允许你写

f (xs :> x) = ...
f [] = ...

但是请注意,所有这些方法仍然需要遍历整个列表的主干,因为它们最终都只是调用您的unsnoc函数。

于 2016-03-30T02:10:36.750 回答
0

对于任意列表,您不能,但对于固定大小的列表,您可以模式匹配到最后一个元素(或任何其他任意元素),例如

lastof4 [_,_,_,x] = x

lastof4 [1..4]
4
于 2016-03-30T02:13:55.693 回答