【问题标题】:guard desugaringguard desugaring
【发布时间】:2011-05-10 00:53:59
【问题描述】:

我经常听到这句话,守卫只是 if-then-else(或 case 语句)的语法糖。

有人可以为以下实例脱糖吗:

halfOf :: Int -> Int
halfOf x | even x = div x 2

(函数故意偏)

谢谢,

【问题讨论】:

    标签: haskell syntax syntactic-sugar guard


    【解决方案1】:

    模式匹配的语义在标准的以下部分定义:Formal Semantics of Pattern Matching

    与您的问题相关的步骤是 c。如您所见,模式与表单的守卫匹配

    case v of { p | g1 -> e1 ; ...
                  | gn -> en where { decls }
                _     -> e' }
    

    被翻译为没有保护的模式匹配:

    case e' of
    {y ->
       case v of {
           p -> let { decls } in
                if g1 then e1 ... else if gn then en else y ;
            _ -> y }}
    

    因此,模式防护是根据if 定义的,“fallthrough”是通过将表达式绑定到变量来实现的,然后在ifelse 子句中重复一次,然后在您使用的模式中会失败的。

    如果没有案例可以通过(如您的示例),则步骤 b 将插入一个案例,该步骤将插入默认案例 _ -> error "No match"

    【讨论】:

    • 感谢您的参考。我希望能够将分支标记为模式匹配错误,但我可以理解为什么该语言不提供这样的功能。谢谢!
    【解决方案2】:
    halfOf x =
      if even x
      then div x 2
      else error "Incomplete pattern match" 
    

    由未处理的情况触发的确切错误类型未由语言定义指定,并且因编译器而异。

    编辑:如果有多个警卫和/或模式,每个警卫或模式匹配进入前一个案例的非匹配部分。

    compare x y
      | x == y = foo
      | x /= y = bar
    compare _ _ = baz
    

    生产

    compare x y =
      if x == y
      then foo
      else if x /= y
           then bar
           else baz
    

    【讨论】:

    • 耶哈!这里有一个问题。这不是模式匹配错误。如果这行之后还有其他情况会发生什么?
    • @Ozgur:如果你想要一个完整的答案,不要试图用故意用词错误的问题来引诱人们。
    • 哎呀抱歉。没有拖钓的意图。我只是想在这里理解一些东西。真的。
    • 这个答案是正确的,除了消息是“程序错误:{sign 0}”。
    猜你喜欢
    • 2023-03-22
    • 2011-12-11
    • 2020-12-20
    • 1970-01-01
    • 2017-07-16
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    相关资源
    最近更新 更多