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)
有没有办法在最后一个元素上进行模式匹配?
不,因为没有[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个元素,则会触发第一条错误消息,其余列表不为空; 第二个是任何与前两个之一不匹配的列表.
要获取列表的最后一个元素,您需要遍历整个列表.
如果你需要匹配最后一个元素,你可能需要一个类似列表的数据结构,使得这样的匹配有效且易于使用,比如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)
如果您有 GHC 6.10 或更高版本,请使用视图模式。
\n\n\n\n\n视图模式允许在模式内调用视图函数并\n 与结果进行匹配:
\n\nRun Code Online (Sandbox Code Playgroud)\n\nsize (view -> Unit) = 1\nsize (view -> Arrow t1 t2) = size t1 + size t2\n
也就是说,我们添加了一种新形式的模式,写成
\n\nRun Code Online (Sandbox Code Playgroud)\n\nexpression -> pattern\n
这意味着 \xe2\x80\x9c 将表达式应用于我们尝试匹配\n 的内容,然后将该应用程序的结果与\n 模式进行匹配。\xe2\x80\x9d 该表达式可以是任何 Haskell 表达式函数类型,并且可以在当前使用模式的任何地方使用视图模式。
\n
定义head\'
为
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