gambler-0.4.0.0: source/Fold/Shortcut/Examples/Interesting.hs
module Fold.Shortcut.Examples.Interesting
(
{- * Length -} null,
{- * Boolean -} and, or, all, any,
{- * Search -} element, notElement, find, lookup,
{- * Index -} index, findIndex, elementIndex,
)
where
import Fold.Shortcut.Type
import Control.Applicative (liftA2)
import Data.Bool (Bool)
import Data.Eq (Eq, (/=), (==))
import Data.Functor (($>), (<&>))
import Data.Maybe (Maybe (Just, Nothing))
import Fold.Shortcut.Conversion (fold)
import Fold.Shortcut.Utilities (demotivate)
import Numeric.Natural (Natural)
import Prelude ((-))
import Strict (isAlive, isDead)
import qualified Fold.Pure.Examples.Interesting as Fold
{-| 'True' if the input contains no inputs (tenacious) -}
null :: ShortcutFold a Bool
null = ShortcutFold
{ initial = Alive Tenacious ()
, step = \() _ -> Dead ()
, extract = isAlive
}
{-| 'True' if all inputs are 'True' (tenacious) -}
and :: ShortcutFold Bool Bool
and = ShortcutFold
{ initial = Alive Tenacious ()
, step = \_ a -> if a then Alive Tenacious () else Dead ()
, extract = isAlive
}
{-| 'True' if any input is 'True' (tenacious) -}
or :: ShortcutFold Bool Bool
or = ShortcutFold
{ initial = Alive Tenacious ()
, step = \() a -> if a then Dead () else Alive Tenacious ()
, extract = isDead
}
{-| 'True' if all inputs satisfy the predicate (tenacious) -}
all :: (a -> Bool) -> ShortcutFold a Bool
all predicate = ShortcutFold
{ initial = Alive Tenacious ()
, step = \() a -> if predicate a then Alive Tenacious () else Dead ()
, extract = isAlive
}
{-| 'True' if any input satisfies the predicate (tenacious) -}
any :: (a -> Bool) -> ShortcutFold a Bool
any predicate = ShortcutFold
{ initial = Alive Tenacious ()
, step = \_ a -> if predicate a then Dead () else Alive Tenacious ()
, extract = isDead
}
{-| 'True' if any input is equal to the given value (tenacious) -}
element :: Eq a => a -> ShortcutFold a Bool
element a = any (a ==)
{-| 'False' if any input is equal to the given value (tenacious) -}
notElement :: Eq a => a -> ShortcutFold a Bool
notElement a = all (a /=)
{-| The first input that satisfies the predicate, if any (tenacious) -}
find :: (a -> Bool) -> ShortcutFold a (Maybe a)
find ok = ShortcutFold
{ initial = Alive Tenacious ()
, step = \() a -> if ok a then Dead a else Alive Tenacious ()
, extract = \v -> case v of { Dead x -> Just x; _ -> Nothing }
}
{-| The /n/th input, where n=0 is the first input, if the index is in
bounds (tenacious) -}
index :: Natural -> ShortcutFold a (Maybe a)
index i = ShortcutFold
{ initial = Alive Tenacious i
, step = \i' a -> if i' == 0 then Dead a else Alive Tenacious (i' - 1)
, extract = \v -> case v of { Dead x -> Just x; _ -> Nothing }
}
{-| The index of the first input that matches the given value, if any
(tenacious) -}
elementIndex :: Eq a => a -> ShortcutFold a (Maybe Natural)
elementIndex a = findIndex (a ==)
{-| The index of the first input that satisfies the predicate, if any
(tenacious) -}
findIndex :: (a -> Bool) -> ShortcutFold a (Maybe Natural)
findIndex ok = demotivate
(
liftA2 (,) (fold Fold.length) (find ok)
<&> \(n, found) -> found $> (n - 1)
)
{-| The @b@ from the first tuple where @a@ equals the given value,
if any (tenacious) -}
lookup :: Eq a => a -> ShortcutFold (a, b) (Maybe b)
lookup a0 = ShortcutFold
{ initial = Alive Tenacious ()
, step = \() (a, b) -> if a == a0 then Dead b else Alive Tenacious ()
, extract = \v -> case v of { Dead x -> Just x; _ -> Nothing }
}