module Data.Option where
import Control.Applicative
import Control.DeepSeq
import Control.Monad
import Data.Aeson
import GHC.Generics
data Option a
= None
| Some !a
deriving (Show, Eq, Ord, Generic)
instance NFData a => NFData (Option a)
instance Functor Option where
fmap f x =
case x of
None -> None
Some v -> Some (f v)
instance Applicative Option where
pure = Some
f <*> x =
case f of
Some g -> fmap g x
None -> None
instance Monad Option where
(Some x) >>= k = k x
None >>= _ = None
(>>) = (*>)
fail _ = None
instance Monoid a => Monoid (Option a) where
mempty = None
None `mappend` m = m
m `mappend` None = m
Some m1 `mappend` Some m2 = Some (m1 `mappend` m2)
instance Alternative Option where
empty = None
None <|> r = r
l <|> _ = l
instance MonadPlus Option
instance ToJSON a => ToJSON (Option a) where
toJSON = toJSON . optionToMaybe
instance FromJSON a => FromJSON (Option a) where
parseJSON x = maybeToOption <$> parseJSON x
optionToMaybe :: Option a -> Maybe a
optionToMaybe x =
case x of
Some v -> Just v
None -> Nothing
maybeToOption :: Maybe a -> Option a
maybeToOption x =
case x of
Just v -> Some v
Nothing -> None