Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

standard specialization of Either where type of Left and Right is the same

Is there a standard specialization of Either in Haskell or Scala that makes the types contained in the Left and Right the same type?

In Haskell, I want something like this:

data SpecializedEither a = Left a | Right a

This might also be considered a slight generalization of Maybe that makes Nothing hold a value.

edit: Ganesh raises a very good point that a Monad instance can't be defined for this type. Is there a better way to do what I am trying to do?

like image 478
illabout Avatar asked Dec 15 '22 22:12

illabout


1 Answers

There's a standard Monad instance on ((,) e) so long as e is a Monoid

instance Monoid e => Monad ((,) e) where
  return a = (mempty, a)
  (e1, a) >>= f = let (e2, b) = f a in (e1 <> e2, b)

Since Either a a and (Bool, a) are isomorphic (in two ways), we get a Monad instance as soon as we pick a Monoid for Bool. There are two (really four, see comments) such Monoids, the "and" type and the "or" type. Essentially, this choice ends up deciding as to whether the Left or Right side of your either is "default". If Right is default (and thus Left overrides it) then we get

data Either1 a = Left1 a | Right1 a

get1 :: Either1 a -> a
get1 (Left1 a) = a
get1 (Right1 a) = a

instance Monad Either1 where
  return = Right1
  x >>= f = case (x, f (get1 x)) of
    (Right1 _, Right1 b) -> Right1 b
    (Right1 _, Left1  b) -> Left1  b
    (Left1  _, y       ) -> Left1 (get1 y)
like image 153
J. Abrahamson Avatar answered Dec 28 '22 23:12

J. Abrahamson