Search code examples
haskelltypessingleton-type

Limiting the Types that a Type Paramater Can Take On in Data Declarations


I'm aware that Haskell has paramaterized data types:

data Maybe a = Nothing | Just a

But is there a way to limit the sort of types that a can denote? In particular, I'd like to create a type

data Tag a = Tag a

such that a can take either the type TagPrimitive or the type TagComplex (however, I don't want it to be possible that a is of type, say, Integer or String or something that makes no sense in my program).

Is this possible?


Solution

  • Your proposed Tag type is a bit odd: it is a parameterized type which may be either specialized to a type that can only contain TagPrimitives or may be specialized to a type that can only contain TagComplexs. But this seems a bit pointless: we already have the two specialized types TagPrimitive and TagComplex to serve these two roles.

    Instead, I propose that what you actually wanted was a single type that can contain values of either type. For this I recommend cooking up a fresh sum type:

    data Tag = Primitive TagPrimitive | Complex TagComplex
        deriving (Eq, Ord, Read, Show)
    

    For early prototypes, you might get away with using the canonical sum type, Either, as in

    type Tag = Either TagPrimitive TagComplex
    

    but I suspect that as your program grows, this will become an increasingly bad choice.