2013-10-25 204 views
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 

甚至这个(如果有一些计算,而不是仅仅返回constant_这将是有益的)

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

回答

6

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 
+0

在后面的例子中,您可以删除否则 – Ingo

+0

好点,谢谢。 – Joni

4

Unfotunately你不能做到这一点,一个简单的解决方案是

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 
1

您可以假冒“或图案”与连接在ghc ticket 3919一个quasiquote。

随着即将发布的(ghc-7.10?)pattern synonyms,您可能可以定义一个pattern p1 :| p2 = ???,它与上一个链接中的quasiquote做的脱糖相同。