【问题标题】:Pattern matching, matching multiple character模式匹配,匹配多个字符
【发布时间】:2013-10-25 14:15:30
【问题描述】:

如果我有一个函数,它接受一个字符串并说返回一个 int,我可以使用模式匹配来匹配字符串的第一个字符:

f :: String -> Int
f ('A' : _) = 1
f ('B' : _) = 0
f ('C' : _) = 1
f _ = 2

有没有办法将 A 或 C 匹配为一个? 比如:

f :: String -> Int
f ('A'||'C' : _) = 1
f ('B' : _) = 0
f _ = 2

甚至这个(如果有一些计算而不是仅仅返回一个常量,这将很有用)

f :: String -> Int
f ('A' : _)
f ('C' : _) = 1
f ('B' : _) = 0
f _ = 2

【问题讨论】:

    标签: haskell pattern-matching


    【解决方案1】:

    Haskell 在模式匹配中没有交替。您可以使用递归解决问题:

    f :: String -> Int
    f ('A' : rest) = f ('C' : rest)
    f ('B' : _) = 0
    f ('C' : _) = 1
    f _ = 2
    

    你可以考虑使用守卫:

    f ('B' : _) = 0
    f (x : _) | x `elem` "AC" = 1
    f _ = 2
    

    【讨论】:

    • 在后一个例子中,你可以直接放弃
    【解决方案2】:

    不幸的是你不能这样做,一个简单的解决方案是

     f (x:_) | x == 'A' || x == 'C' = 1
             | x == 'B"             = 0
             | otherwise            = 2
    
     f ('B':_)  = 2
     f (x:_) | x == 'A' || x == 'C' = 1
     f _        = 0
    

    这使用了守卫,但它不是非常匹配模式,它真的就像ifs 的链

    我可能会这样写

    f ('A':_) = f "C"
    f ('C':_) = 1
    f ('B':_) = 0
    f _       = 2
    

    【讨论】:

      【解决方案3】:

      您可以使用附加在ghc ticket 3919 的准引号来伪造“或模式”。

      使用即将推出的 (ghc-7.10?) pattern synonyms,您或许可以定义一个 pattern p1 :| p2 = ???,它与上一个链接中的 quasiquote 执行相同的去糖操作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-02
        • 2012-04-01
        • 2014-05-28
        • 1970-01-01
        • 2011-10-20
        • 1970-01-01
        • 1970-01-01
        • 2012-04-24
        相关资源
        最近更新 更多