我正在和Miran Lipovaca一起学习Haskell的“为了好大学而学习哈斯克尔!”。在第82页,它说
如果模式匹配失败,列表推导将继续移动到下一个元素,失败的元素将不会包含在结果列表中。
示例:
ghci> let xs = [(1,3),(4,3),(2,4),(5,3),(5,6),(3,1)]
ghci> [a+b | (a, b) <- xs]
[4,7,6,8,11,4]
我的问题是模式匹配是如何失败的? 他的意思是什么?我真的不明白。可能是因为我的英语很弱。我请你举个例子,因为我认为这本书没有给出任何模式匹配失败的例子。
我想过如果列表包含列表解析无法处理的类型,那么它会移动到下一个元素但是如果我以这种方式更改列表:
let xs = [(1,3),(4,3),(2,4),(5,3),True,(5,6)]
然后它甚至没有编译,因为它“无法匹配预期的类型”......
答案 0 :(得分:8)
以下是在GHCi演示的列表推导中模式匹配失败的几个案例:
Prelude> [ () | True <- [True, False,True] ]
[(),()]
Prelude> [ x | (x, True) <- [(1,True), (2,False), (3,True)] ]
[1,3]
Prelude> [ x+1 | Left x <- [Left 1, Right "Hello", Right "world", Left 2] ]
[2,3]
请注意,某些模式永远不会失败,例如x
,(x,y)
或(x,(a,b),z)
。这是因为它们只匹配只有一个构造函数的类型,它必须匹配唯一的构造函数。
通常,模式匹配涉及多个分支,例如
case someValue of
Left x -> ...
Right y -> ...
foo Nothing = ...
foo (Just x) = ...
在这些情况下,如果我们忘记处理构造函数,那么在发生这种情况时会出现运行时错误。 (打开警告有助于避免这种情况!)。
在列表推导生成器p <- ...
中,我们只能指定一种模式。但是,特殊规则适用:模式匹配失败不是错误,而是被忽略。
答案 1 :(得分:7)
那是不模式匹配失败的一个例子(元组模式匹配总是)。这将是一个例子:
Prelude> xs = [Just (1,3), Just (4,3), Nothing, Just (5,3), Nothing]
Prelude> [a+b | Just (a, b) <- xs]
[4,7,8]
此处,模式Just (a, b)
仅匹配元素Just (1,3)
,Just (4,3)
和Just (5,3)
,但不匹配Nothing
,因此这些位置只是' t在最终名单中出现。