Jonathan.
Jonathan.

Reputation: 55554

Pattern matching, matching multiple character

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

Upvotes: 5

Views: 1769

Answers (3)

aavogt
aavogt

Reputation: 1308

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.

Upvotes: 1

Joni
Joni

Reputation: 111259

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

Upvotes: 7

daniel gratzer
daniel gratzer

Reputation: 53881

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

Upvotes: 4

Related Questions