4
votes

If I have a function that takes a string and say returns an int, I can match the first character of the string, using pattern matching:

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

is there a way to match A or C in one? Something like:

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

or even this (which would be useful if there is some calculation rather than just returning a constant_)

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

3 Answers

7
votes

Haskell does not have alternation in the pattern matching. You could solve the problem using recursion:

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

You might consider using guards:

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

Unfotunately you can't do this, a simple solution is

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

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

This uses guards, but it's not terribly pattern match-y, it's really just like a chain of ifs

I'd probably write this as

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

You can fake 'or-patterns' with a quasiquote that is attached at ghc ticket 3919.

With the forthcoming (ghc-7.10?) pattern synonyms, you might be able to define a pattern p1 :| p2 = ??? which does the same de-sugaring that the quasiquote in the previous link does.