{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE DeriveGeneric #-}
#if MIN_VERSION_base(4,9,0)
#define LIFTED_FUNCTOR_CLASSES 1
#else
#if MIN_VERSION_transformers(0,5,0)
#define LIFTED_FUNCTOR_CLASSES 1
#else
#if MIN_VERSION_transformers_compat(0,5,0) && !MIN_VERSION_transformers(0,4,0)
#define LIFTED_FUNCTOR_CLASSES 1
#endif
#endif
#endif
module Data.Strict.Maybe (
Maybe(..)
, isJust
, isNothing
, fromJust
, fromMaybe
, maybe
, listToMaybe
, maybeToList
, catMaybes
, mapMaybe
) where
import Prelude (Functor (..), Eq (..), Ord (..), Show (..), Read (..), Bool (..), (.)
,error, Ordering (..), ($), showString, showParen, return, lex, readParen)
import Control.Applicative (pure, (<$>))
import Data.Monoid (Monoid (..))
import Data.Semigroup (Semigroup (..))
import Data.Foldable (Foldable (..))
import Data.Traversable (Traversable (..))
import qualified Prelude as L
import Control.DeepSeq (NFData (..))
import Data.Binary (Binary (..))
import Data.Hashable (Hashable(..))
import Data.Hashable.Lifted (Hashable1 (..))
import GHC.Generics (Generic)
import Data.Data (Data (..), Typeable)
#if __GLASGOW_HASKELL__ >= 706
import GHC.Generics (Generic1)
#endif
#if MIN_VERSION_deepseq(1,4,3)
import Control.DeepSeq (NFData1 (..))
#endif
#ifdef LIFTED_FUNCTOR_CLASSES
import Data.Functor.Classes (Eq1 (..), Ord1 (..), Read1 (..), Show1 (..))
#else
import Data.Functor.Classes (Eq1 (..), Ord1 (..), Read1 (..), Show1 (..))
#endif
data Maybe a = Nothing | Just !a
deriving (Eq, Ord, Read, Show, Typeable, Data, Generic
#if __GLASGOW_HASKELL__ >= 706
, Generic1
#endif
)
toStrict :: L.Maybe a -> Maybe a
toStrict L.Nothing = Nothing
toStrict (L.Just x) = Just x
toLazy :: Maybe a -> L.Maybe a
toLazy Nothing = L.Nothing
toLazy (Just x) = L.Just x
isJust :: Maybe a -> Bool
isJust Nothing = False
isJust _ = True
isNothing :: Maybe a -> Bool
isNothing Nothing = True
isNothing _ = False
fromJust :: Maybe a -> a
fromJust Nothing = error "Data.Strict.Maybe.fromJust: Nothing"
fromJust (Just x) = x
fromMaybe :: a -> Maybe a -> a
fromMaybe x Nothing = x
fromMaybe _ (Just y) = y
maybe :: b -> (a -> b) -> Maybe a -> b
maybe x _ Nothing = x
maybe _ f (Just y) = f y
listToMaybe :: [a] -> Maybe a
listToMaybe [] = Nothing
listToMaybe (a:_) = Just a
maybeToList :: Maybe a -> [a]
maybeToList Nothing = []
maybeToList (Just x) = [x]
catMaybes :: [Maybe a] -> [a]
catMaybes ls = [x | Just x <- ls]
mapMaybe :: (a -> Maybe b) -> [a] -> [b]
mapMaybe _ [] = []
mapMaybe f (x:xs) = case f x of
Nothing -> rs
Just r -> r:rs
where
rs = mapMaybe f xs
instance Semigroup a => Semigroup (Maybe a) where
Nothing <> m = m
m <> Nothing = m
Just x1 <> Just x2 = Just (x1 <> x2)
#if MIN_VERSION_base(4,11,0)
instance Semigroup a => Monoid (Maybe a) where
mempty = Nothing
#else
instance Monoid a => Monoid (Maybe a) where
mempty = Nothing
Nothing `mappend` m = m
m `mappend` Nothing = m
Just x1 `mappend` Just x2 = Just (x1 `mappend` x2)
#endif
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just x) = Just (f x)
instance Foldable Maybe where
foldMap _ Nothing = mempty
foldMap f (Just x) = f x
instance Traversable Maybe where
traverse _ Nothing = pure Nothing
traverse f (Just x) = Just <$> f x
instance NFData a => NFData (Maybe a) where
rnf = rnf . toLazy
#if MIN_VERSION_deepseq(1,4,3)
instance NFData1 Maybe where
liftRnf rnfA = liftRnf rnfA . toLazy
#endif
instance Binary a => Binary (Maybe a) where
put = put . toLazy
get = toStrict <$> get
instance Hashable a => Hashable (Maybe a) where
hashWithSalt salt = hashWithSalt salt . toLazy
instance Hashable1 Maybe where
liftHashWithSalt hashA salt = liftHashWithSalt hashA salt . toLazy
#ifdef LIFTED_FUNCTOR_CLASSES
instance Eq1 Maybe where
liftEq f (Just a) (Just a') = f a a'
liftEq _ Nothing Nothing = True
liftEq _ _ _ = False
instance Ord1 Maybe where
liftCompare _ Nothing Nothing = EQ
liftCompare _ Nothing (Just _) = LT
liftCompare _ (Just _) Nothing = GT
liftCompare f (Just a) (Just a') = f a a'
instance Show1 Maybe where
liftShowsPrec _ _ _ Nothing = showString "Nothing"
liftShowsPrec sa _ d (Just a) = showParen (d > 10)
$ showString "Just "
. sa 11 a
instance Read1 Maybe where
liftReadsPrec ra _ d = readParen (d > 10) cons where
cons s0 = do
(ident, s1) <- lex s0
case ident of
"Nothing" -> return (Nothing, s1)
"Just" -> do
(a, s2) <- ra 11 s1
return (Just a, s2)
_ -> []
#else
instance Eq1 Maybe where eq1 = (==)
instance Ord1 Maybe where compare1 = compare
instance Show1 Maybe where showsPrec1 = showsPrec
instance Read1 Maybe where readsPrec1 = readsPrec
#endif