data-msgpack-types-0.0.3: src/Data/MessagePack/Types/Option.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
module Data.MessagePack.Types.Option
( Option (..)
) where
import Control.Applicative (Alternative (..),
Applicative (..), (<$>))
import Control.Monad (Monad (..), MonadPlus (..))
import Data.Data (Data)
import Data.Foldable (Foldable)
import Data.Traversable (Traversable)
import Data.Typeable (Typeable)
import Test.QuickCheck.Arbitrary (Arbitrary (..))
import qualified Test.QuickCheck.Gen as Gen
import Data.MessagePack.Types.Class (MessagePack (..))
import Data.MessagePack.Types.Object (Object (..))
data Option a
= None
| Some a
deriving (Eq, Ord, Show, Read, Foldable, Functor, Traversable, Data, Typeable)
instance Applicative Option where
pure = Some
Some f <*> m = fmap f m
None <*> _ = None
instance Monad Option where
return = Some
None >>= _ = None
Some x >>= f = f x
#if (MIN_VERSION_base(4,13,0))
instance MonadFail Option where
#endif
fail _ = None
instance Alternative Option where
empty = None
None <|> x = x
x <|> _ = x
instance MonadPlus Option where
mzero = empty
mplus = (<|>)
instance MessagePack a => MessagePack (Option a) where
toObject None = ObjectNil
toObject (Some a) = toObject a
fromObject ObjectNil = return None
fromObject x = Some <$> fromObject x
instance Arbitrary a => Arbitrary (Option a) where
arbitrary = Gen.oneof
[ pure None
, Some <$> arbitrary
]