I have to combined Maybe
and Either
into MayEither
, with three constructors for Left
, Right
and Nothing
called MyLeft
, MyRight
and MyNothing
.
This is what I did:
data MayEither = Maybe { myNothing :: Nothing }
| Either { myLeft :: Left }
| Either { myRight :: Right } deriving Show
But this gives me a Multiple declarations of ‘Either’
error.
How can I properly combine the types?
CodePudding user response:
Two things need to happen:
- You need to give distinct names for each of your data constructors.
- You need to give the types of the fields in your records.
Note that Nothing
, Left
, and Right
are data constructors for the Maybe
and Either
types -- they are not themselves types! So claiming that a field has type Nothing
isn't quite right. Similarly, Maybe
and Either
are type constructors, so naming your data constructors after them is at best misleading, and in this case almost certainly simply wrong.
So let's try again. First we'll pick new data constructor names.
data MyEither = MyNothing { myNothing :: <TODO> }
| MyLeft { myLeft :: <TODO> }
| MyRight { myRight :: <TODO> }
Now, what type should myNothing
have? Well, the whole point of Nothing
/MyNothing
is that there's, well, nothing there. So we shouldn't have that field at all!
data MyEither = MyNothing
| MyLeft { myLeft :: <TODO> }
| MyRight { myRight :: <TODO> }
What type should the myLeft
field have? Well, presumably we'd like to be able to have anything in there. The way to allow that is to parameterize our type -- just like Maybe
takes one type-level argument and Either
takes two type-level arguments. We'll do what Either
does, and take two arguments, so that our myLeft
and myRight
fields can be arbitrary and need not match.
data MyEither a b = MyNothing
| MyLeft { myLeft :: a }
| MyRight { myRight :: b }
This is now valid Haskell. BUT combining record syntax and sum types is almost always a bad idea. I think I would drop the field names entirely, if I were doing this myself.
data MyEither a b = MyNothing
| MyLeft a
| MyRight b
-- OR
data MyEither a b = MyNothing | MyLeft a | MyRight b