matcher-0.1.1.2: library/Matcher.hs
module Matcher
(
Matcher,
run,
equals,
satisfies,
converts,
whatever,
)
where
import Matcher.Prelude
import qualified Success.Pure
-- |
-- Converts the matcher into a conversion function,
-- which results in either a successful result or a failure.
{-# INLINABLE run #-}
run :: Matcher a b -> a -> Either Text b
run (Matcher (ReaderT successFn)) input =
{-# SCC "run" #-}
either (Left . fromMaybe "") Right $
Success.Pure.asEither $
successFn input
-- |
-- A composable abstraction for checking or converting a context value.
newtype Matcher a b =
Matcher (ReaderT a (Success Text) b)
deriving (Functor, Applicative, Alternative, Monad, MonadPlus)
instance Profunctor Matcher where
{-# INLINE lmap #-}
lmap fn (Matcher (ReaderT successFn)) =
Matcher (ReaderT (successFn . fn))
{-# INLINE rmap #-}
rmap =
fmap
instance Category Matcher where
{-# INLINE id #-}
id =
Matcher $
ReaderT $
Success.Pure.success
{-# INLINE (.) #-}
(.) (Matcher (ReaderT successFn2)) (Matcher (ReaderT successFn1)) =
Matcher $
ReaderT $
successFn1 >=> successFn2
instance Arrow Matcher where
{-# INLINE arr #-}
arr f =
Matcher $
ReaderT $
Success.Pure.success . f
{-# INLINE first #-}
first (Matcher (ReaderT successFn)) =
Matcher $
ReaderT $
\(a, b) ->
fmap (\a -> (a, b)) $
successFn a
-- |
-- Tests the matched value on equality with the provided value.
{-# INLINE equals #-}
equals :: Eq a => a -> Matcher a ()
equals reference =
{-# SCC "equals" #-}
Matcher $
ReaderT $
\input ->
if input == reference
then Success.Pure.success ()
else Success.Pure.failure "The input doesn't equal the expected value"
-- |
-- Checks whether the matched value satisfies the provided predicate.
{-# INLINE satisfies #-}
satisfies :: (a -> Bool) -> Matcher a ()
satisfies predicate =
{-# SCC "satisfies" #-}
Matcher $
ReaderT $
\input ->
if predicate input
then Success.Pure.success ()
else Success.Pure.failure "The input doesn't satisfy the predicate"
-- |
-- Tries to convert the matched value to an output value,
-- with 'Either' encoding the success or failure of the conversion.
{-# INLINE converts #-}
converts :: (a -> Either Text b) -> Matcher a b
converts match =
{-# SCC "converts" #-}
Matcher $
ReaderT $
either Success.Pure.failure Success.Pure.success . match
-- |
-- The matcher, which is always satisfied.
{-# INLINE whatever #-}
whatever :: Matcher a ()
whatever =
{-# SCC "whatever" #-}
Matcher $
ReaderT $
const $
pure ()