Reputation: 13908
I'm trying to declare a datatype that is a list of Either
types.
data EitherInts = [Either Int Int]
But when I try to compile this type I get an error:
Cannot parse data constructor in a data/newtype declaration: [Either Int Int]
I have no idea why. What am I doing wrong?
Upvotes: 6
Views: 7616
Reputation: 92147
data
is for defining new algebraic data types, which must each have their own constructor(s). So you could write
data EitherInts = EitherInts [Either Int Int]
But you probably don't mean this: you want some kind of type synonym. There are two possibilities:
type EitherIntsType = [Either Int Int]
or
newtype EitherIntsNewtype = EitherInts [Either Int Int]
The first, using type
, acts exactly like [Either Int Int]
: a value such as [Left 2]
is a valid value of the new EitherIntsType
type. It's just a new, abbreviated name for that existing type, and can be used interchangeably with it. This approach is fine when you just want to be able to use a different name for an existing type: for clarity, or to give a shorter name to a much longer type.
The second, using newtype
, is more heavy-weight. It acts more like data
, with its own constructor. Values like [Left 2]
are not valid values of the new EitherIntsNewtype
type. Instead, you must write EitherintsNewtype [Left 2]
to lift an existing list value, and you must pattern-match to extract values. This approach is better when you want the compiler's help making sure you don't mix up lifted and unlifted values, or when you want something like an existing type but with different typeclass instances (because you can give your newtype
its own typeclass instances, which a type
can't have).
Upvotes: 13