Avoiding an incomplete pattern match

Viewed 178

Consider the following code:

data A
data B

f :: A -> B
f = undefined

data T = TA A | TB B
data ListT = ListTA [A] | ListTB [B]

g :: [T] -> ListT
g l = 
  let
    f' :: T -> B
    f' (TA x) = f x
    f' (TB x) = x
    isA :: T -> Bool
    isA TA{} = True
    isA TB{} = False
  in
    case (all isA l) of
      True -> ListTA (map (\(TA x) -> x) l)
      False -> ListTB (map f' l)

main = pure ()

The idea behind this is I've got a list of either As or Bs mixed together. I can convert A -> B but not the other way around. Based on this list, I want to make either a list of As or list of Bs, the former if all my original list elements are As, the latter if at least one is a B.

The above code compiles (and I'm guessing will work) but the incomplete pattern match in the map (\(TA x) -> x) l makes me just a little uncomfortable. Is such an incomplete match just a necessity of what I'm doing here? Also, am I reinventing the wheel, is there something that generalises what I'm doing here?

3 Answers
Related