模式匹配,匹配多个字符

时间:2013-10-25 14:15:31

标签: haskell pattern-matching

如果我有一个带字符串的函数并且返回一个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

3 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:4)

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

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

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

这使用了守卫,但它并不是非常模式匹配,它实际上就像一串if s

我可能会把它写成

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

答案 2 :(得分:1)

您可以使用ghc ticket 3919附加的quasiquote伪装'或 - 模式'。

使用即将发布的(ghc-7.10?)pattern synonyms,您可以定义一个pattern p1 :| p2 = ???,它与上一个链接中的quasiquote具有相同的去糖效果。