I have defined a Haskell type similar to the following:

data TypeData = TypeA Int | TypeB String | TypeC Char deriving (Eq, Show)

At some point, I need a way to filter a [TypeData] for all non-TypeC instances. The signature of the function I am trying to write is:

-- Returns a tuple containing (TypeC elements, non-TypeC elements)
partitionTypeCs :: [TypeData] -> ([TypeData],[TypeData])

The partition function seemed suitable for this:

-- Attempt:
partitionTypeCs data = partition (TypeData -> Bool) data

However, I cannot figure out what function would match the type signature TypeData -> Bool. It looks like I need a function that can determine if a type instance is of a specific instance. I know I can use pattern matching for that by writing another function (isTypeC (TypeC _) = True), but is there a more generic way or an lineline way of matching type instances?

score:5

Accepted answer

I would do it like this:

partitionTypeCs = partition f where
  f (TypeC _) = False
  f _ = True

I must admit that I don't understand why you don't like this. You can't compare against a constructor using equality because there is an unknown parameter involved. Pattern matching does exactly what must be done here.

score:3

Pattern matching is pretty much the answer here. It'd take you 3 additional lines (including type signature), so it's not like it's a long solution. You could probably write some template haskell that could do it in general, but that seems like too complicated a solution for something so simple.

isTypeC :: TypeData -> Bool
isTypeC (TypeC _) = True
isTypeC _ = False

Related Query

More Query from same tag