[Solved] About single action for multiple pattern matched

The case of pattern matching can assist me in defining distinct actions for specific types that match a given pattern. However, the syntax doesn’t seem to support handling multiple matched patterns with a single action.

For example,

data T = A|B|C

run :: T -> IO ()
run t =
  case t of
    A -> putStrLn "A"
    B -> putStrLn "B"
    C -> putStrLn "C"

I am unable to write something like the following:

case t of
  A,B -> putStrLn "A|B" -- compile error
  C -> putStrLn "C

In my experience with Rust and OCaml, this functionality was present in both languages. I have attempted to find a way to accomplish this in Haskell, but it appears to be quite challenging. Can anyone provide assistance?

Thank you.

2 Likes

The “Or Patterns” proposal was recently accepted but not implemented yet. It would allow you to write:

  case t of
    one of A, B -> putStrLn "A|B"
    C -> putStrLn "C"

In the meantime you can use a helper variable:

  case t of
    A -> ab
    B -> ab
    C -> putStrLn "C"
  where ab = putStrLn "A|B"

If you run into such a pattern very often you can create a pattern synonym:

{-# LANGUAGE PatternSynonyms, ViewPatterns #-}

aOrB :: T -> Bool
aOrB A = True
aOrB B = True
aOrB C = False

pattern AOrB :: T
pattern AOrB <- (aOrB -> True)
{-# COMPLETE AOrB, C #-}

Then you can write:

  case t of
    AOrB -> putStrLn "A|B"
    C -> putStrLn "C"
4 Likes

Thank you! Learned a lot.

1 Like