4

当给定一个空字符串时,以下两个函数的行为不同:

guardMatch l@(x:xs) 
    | x == '-'        = "negative " ++ xs
    | otherwise       = l

patternMatch ('-':xs) = "negative " ++ xs
patternMatch l        = l

这是我的输出:

*Main> guardMatch ""
"*** Exception: matching.hs:(1,1)-(3,20): Non-exhaustive patterns in function guardMatch

*Main> patternMatch ""
""

问题:为什么“否则”关闭不捕获空字符串?

4

3 回答 3

13

otherwise是在模式范围内,只能l@(x:xs)匹配非空字符串。看看这(有效地)在内部翻译成什么可能会有所帮助:

guardMatch   l = case l of
                   (x  :xs) -> if x == '-' then "negative " ++ xs else l
patternMatch l = case l of
                   ('-':xs) ->                  "negative " ++ xs
                   _        ->                                         l

(实际上,我认为 theif被翻译成case+ 守卫,而不是相反。)

于 2011-07-05T15:55:42.147 回答
9

守卫总是在模式之后进行评估。这是 - 如果模式成功,则尝试保护。在您的情况下,该模式(x:xs)不包括空字符串,因此甚至没有尝试保护,因为该模式失败了。

于 2011-07-05T15:56:15.063 回答
3

其他两个答案当然是完全正确的,但这里有另一种思考方式:如果你写了这个怎么办?

guardMatch l@(x:xs) 
    | x == '-'        = "negative " ++ xs
    | otherwise       = [x]

你希望guardMatch ""是什么?

于 2011-07-06T05:31:05.317 回答