{-# 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 ]