module Data.Either where

import Control.Monad
import Data.Fail
import Data.String

data Either a b = Left a | Right b

instance Functor Hask (Either a) where
    _ $> (Left x) = Left x
    f $> (Right y) = Right (f y)

instance Pointed Hask (Either a) where
    point = Right

instance Applicative Hask (Either a) where
    Right f <$> Right x = Right (f x)
    Left  a <$> _       = Left  a
    _       <$> Left  b = Left  b

instance Monad Hask (Either a) where
    join (Left a)          = Left a
    join (Right (Left a))  = Left a
    join (Right (Right b)) = Right b

instance FromString a => Fail (Either a) where
    fail = Left . fromString
