【问题标题】:patterns vs. guards: otherwise does not match?模式与守卫:否则不匹配?
【发布时间】:2011-09-28 22:48:06
【问题描述】:

以下两个函数在给定空字符串时表现不同:

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 ""
""

问题:为什么'otherwise' close 不能捕获空字符串?

【问题讨论】:

    标签: haskell pattern-matching guard-clause


    【解决方案1】:

    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
    

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

    【讨论】:

    • IIRC if 如你所说。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      您希望guardMatch "" 是什么?

      【讨论】:

      • 好点!正如上面的答案告诉我的那样, (x:xs) 模式只匹配非空列表。
      猜你喜欢
      • 2019-03-01
      • 2015-08-15
      • 1970-01-01
      • 1970-01-01
      • 2017-06-23
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多