module Matcher
(
Matcher,
run,
equals,
satisfies,
converts,
whatever,
)
where
import Matcher.Prelude
import qualified Success.Pure
run :: Matcher a b -> a -> Either Text b
run (Matcher (ReaderT successFn)) input =
either (Left . fromMaybe "") Right $
Success.Pure.asEither $
successFn input
newtype Matcher a b =
Matcher (ReaderT a (Success Text) b)
deriving (Functor, Applicative, Alternative, Monad, MonadPlus)
instance Profunctor Matcher where
lmap fn (Matcher (ReaderT successFn)) =
Matcher (ReaderT (successFn . fn))
rmap =
fmap
instance Category Matcher where
id =
Matcher $
ReaderT $
Success.Pure.success
(.) (Matcher (ReaderT successFn2)) (Matcher (ReaderT successFn1)) =
Matcher $
ReaderT $
successFn1 >=> successFn2
instance Arrow Matcher where
arr f =
Matcher $
ReaderT $
Success.Pure.success . f
first (Matcher (ReaderT successFn)) =
Matcher $
ReaderT $
\(a, b) ->
fmap (\a -> (a, b)) $
successFn a
equals :: Eq a => a -> Matcher a ()
equals reference =
Matcher $
ReaderT $
\input ->
if input == reference
then Success.Pure.success ()
else Success.Pure.failure "The input doesn't equal the expected value"
satisfies :: (a -> Bool) -> Matcher a ()
satisfies predicate =
Matcher $
ReaderT $
\input ->
if predicate input
then Success.Pure.success ()
else Success.Pure.failure "The input doesn't satisfy the predicate"
converts :: (a -> Either Text b) -> Matcher a b
converts match =
Matcher $
ReaderT $
either Success.Pure.failure Success.Pure.success . match
whatever :: Matcher a ()
whatever =
Matcher $
ReaderT $
const $
pure ()