List的最后一个元素的模式匹配

Nic*_*nin 4 haskell pattern-matching

我们使用(x:xs)模式匹配第一个元素,如下例所示:

head' :: [a] -> a  
head' xs = case xs of [] -> error "No head for empty lists!"  
                      (x:_) -> x  
Run Code Online (Sandbox Code Playgroud)

有没有办法在最后一个元素上进行模式匹配?

che*_*ner 6

不,因为没有[a] -> a -> [a]匹配的类型构造函数.

您可以使用[]:进行模式匹配,因为根据定义,它们是列表值的构建块.[]创建一个空列表的方式.:是从元素和另一个列表构建新列表方法.像append这样的函数不会自己创建新列表; 它们返回:和/或创建的列表[].


例外情况是,如果您事先知道列表的长度,在这种情况下,您可以通过显式匹配所有元素来匹配最后一个元素.

lastOfFour :: [a] -> a
lastOfFour (_:_:_:x:[]) = x
lastOfFour (_:_:_:_:_) = error "Too many elements"
lastOfFour _ = error "Too few elements"
Run Code Online (Sandbox Code Playgroud)

如果您可以匹配至少4个元素,则会触发第一条错误消息,其余列表不为空; 第二个是任何与前两个之一不匹配的列表.


Ed'*_*'ka 5

要获取列表的最后一个元素,您需要遍历整个列表.
如果你需要匹配最后一个元素,你可能需要一个类似列表的数据结构,使得这样的匹配有效且易于使用,比如Sequence(两端的O(1)):

{-# LANGUAGE OverloadedLists #-}

import Data.Sequence

last' :: Seq a -> a
last' Empty = error "Empty sequence"
last' (_:|>a) = a

test = last' [1..5]
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,`:|>`实际上是*模式同义词*而不是数据构造函数.但它是一个合理的模式同义词,因为底层操作(`viewr`和`|>`)是O(1)(摊销,但即使对于持久使用也是有效的).基本上,`:|>`和它的双胞胎`:<|`只是一个比实际构造函数慢的常数因子. (2认同)

Gre*_*con 1

如果您有 GHC 6.10 或更高版本,请使用视图模式

\n\n
\n

视图模式允许在模式内调用视图函数并\n 与结果进行匹配:

\n\n
size (view -> Unit) = 1\nsize (view -> Arrow t1 t2) = size t1 + size t2\n
Run Code Online (Sandbox Code Playgroud)\n\n

也就是说,我们添加了一种新形式的模式,写成

\n\n
expression -> pattern\n
Run Code Online (Sandbox Code Playgroud)\n\n

这意味着 \xe2\x80\x9c 将表达式应用于我们尝试匹配\n 的内容,然后将该应用程序的结果与\n 模式进行匹配。\xe2\x80\x9d 该表达式可以是任何 Haskell 表达式函数类型,并且可以在当前使用模式的任何地方使用视图模式。

\n
\n\n

定义head\'

\n\n
expression -> pattern\n
Run Code Online (Sandbox Code Playgroud)\n\n

它按您的预期工作。

\n\n
{-# LANGUAGE ViewPatterns #-}\n\nhead\' :: [a] -> a\nhead\' (last -> l) = l\n
Run Code Online (Sandbox Code Playgroud)\n