module Data.Vinyl.Utils.Operator (
operator
, (/$/), (/$$/), (\$\), (\$$\), (\&&\), (\||\)
, p
) where
import Control.Applicative hiding (Const)
import Data.Functor.Contravariant
import Data.Monoid
import Data.Vinyl
import Data.Vinyl.Functor
operator :: (forall t. f t -> g t -> h t) -> Rec f rs -> Rec g rs -> Rec h rs
operator _ RNil RNil = RNil
operator f (a :& as) (b :& bs) = (f a b) :& operator f as bs
(/$/) :: Functor f => Rec ((->) a) rs -> Rec (Const (f a)) rs -> Rec f rs
(/$/) = operator (\f (Const x) -> f <$> x)
(/$$/) :: Rec (Compose ((->) a) f) rs -> Rec (Const a) rs -> Rec f rs
(/$$/) = operator (\(Compose f) (Const x) -> f x)
(\$\) :: Functor f => Rec (Op a) rs -> Rec f rs -> Rec (Const (f a)) rs
(\$\) = operator (\(Op f) x -> Const $ f <$> x)
(\$$\) :: Rec (Compose (Op a) f) rs -> Rec f rs -> Rec (Const a) rs
(\$$\) = operator (\(Compose (Op f)) x -> Const $ f x)
predicate (Predicate p) x = Const $ p <$> x
(\&&\) :: forall f rs. Applicative f => Rec Predicate rs -> Rec f rs -> f Bool
(\&&\) p r = go result $ pure True
where
go :: Rec (Const (f Bool)) xs -> f Bool -> f Bool
go RNil b = b
go (Const a :& as) b = go as $ (&&) <$> a <*> b
result :: Rec (Const (f Bool)) rs
result = operator predicate p r
(\||\) :: forall f rs. Applicative f => Rec Predicate rs -> Rec f rs -> f Bool
(\||\) p r = go result $ pure False
where
go :: Rec (Const (f Bool)) xs -> f Bool -> f Bool
go RNil b = b
go (Const a :& as) b = go as $ (||) <$> a <*> b
result :: Rec (Const (f Bool)) rs
result = operator predicate p r
p :: (a -> Bool) -> Predicate a
p = Predicate