我正在阅读一个使用以下示例的教程(我将稍微概括一下):
f :: Foo -> (Int, Foo) ... fList :: Foo -> [Int] fList foo = x : fList bar where (x, bar) = f foo
我的问题在于,似乎你可以参考,x
并且bar
,通过名称,在获得它们的元组之外.如果我的猜测是正确的,这似乎就像在其他语言中解构参数列表一样.(换句话说,我没有做以下:)
fList foo = (fst tuple) : fList (snd tuple) where tuple = f foo
我对这种行为是对的吗?在我读过的教程/书籍中,我从未见过它.有人能指出我有关这个问题的更多信息吗?
编辑:任何事情(列表,数组等)都可以以类似的方式进行解构,或者你只能用元组做到这一点吗?
看到你的编辑,我想你的问题是模式匹配.
并回答你的问题:是的,你可以构建任何东西,你也可以使用构造函数"解构".例如,您可能熟悉这种模式匹配形式:
head :: [a] -> a head (x:xs) = x head [] = error "Can't take head of empty list"
但是,有更多地方可以使用模式匹配,其他有效表示法是:
head xs = case xs of (y:ys) -> y [] -> error "Can't take head of empty list" head xs = let (y:ys) = xs in y head xs = y where (y:ys) = xs
请注意,最后两个示例与第一个示例略有不同,因为当您使用空列表调用它们时,它们会给出不同的错误消息.
虽然这些示例特定于列表,但您可以对其他数据类型执行相同操作,如下所示:
first :: (a, b) -> a first tuple = x where (x, y) = tuple second :: (a, b) -> b second tuple = let (x, y) = tuple in y fromJust :: Maybe a -> a fromJust ma = x where (Just x) = ma
同样,如果你调用它,最后一个函数也会崩溃Nothing
.
总结一下; 如果你能使用构造创造的东西(像(:)
和[]
对列表或(,)
元组,或Nothing
与Just
对可能),则可以使用那些相同的构造做模式匹配的各种方式.