4

如果我有一个接受字符串并说返回 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
4

3 回答 3

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
于 2013-10-25T14:25:17.123 回答
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

这使用了守卫,但它不是非常模式匹配,它实际上就像一个ifs链

我可能会把它写成

f ('A':_) = f "C"
f ('C':_) = 1
f ('B':_) = 0
f _       = 2
于 2013-10-25T14:25:38.163 回答
1

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

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

于 2013-10-25T16:12:38.040 回答