Reputation: 13
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?
Upvotes: 0
Views: 222
Reputation: 152707
Two things need to happen:
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 MayEither = 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 MayEither = 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 MayEither 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 MayEither a b = MyNothing
| MyLeft a
| MyRight b
-- OR
data MayEither a b = MyNothing | MyLeft a | MyRight b
Upvotes: 7