-- | Strict data types for use as internal accumulators that don't space leak

module Control.Foldl.Internal (
    -- * Strict maybe
      Maybe'(..)
    , lazy
    , strict

    -- * Strict Either
    , Either'(..)
    , hush

    -- * Strict Pair
    , Pair(..)
    ) where

-- | A strict 'Maybe'
data Maybe' a = Just' !a | Nothing'

-- | Convert 'Maybe'' to 'Maybe'
lazy :: Maybe' a -> Maybe a
lazy :: forall a. Maybe' a -> Maybe a
lazy  Maybe' a
Nothing' = forall a. Maybe a
Nothing
lazy (Just' a
a) = forall a. a -> Maybe a
Just a
a
{-# INLINABLE lazy #-}

-- | Convert 'Maybe' to 'Maybe''
strict :: Maybe a -> Maybe' a
strict :: forall a. Maybe a -> Maybe' a
strict  Maybe a
Nothing  = forall a. Maybe' a
Nothing'
strict (Just a
a ) = forall a. a -> Maybe' a
Just' a
a
{-# INLINABLE strict #-}

-- | A strict 'Either'
data Either' a b = Left' !a | Right' !b

-- | Convert 'Either'' to 'Maybe'
hush :: Either' a b -> Maybe b
hush :: forall a b. Either' a b -> Maybe b
hush (Left'  a
_) = forall a. Maybe a
Nothing
hush (Right' b
b) = forall a. a -> Maybe a
Just b
b
{-# INLINABLE hush #-}

data Pair a b = Pair !a !b