[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.

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"

Thank you! Learned a lot.