{-# LANGUAGE LambdaCase #-}

module Data.Range.Typed.Algebra.Predicate where

import Control.Applicative
import Data.Range.Typed.Algebra.Internal

predicateAlgebra :: Algebra RangeExprF (a -> Bool)
predicateAlgebra :: forall a. Algebra RangeExprF (a -> Bool)
predicateAlgebra =
  \case
    Invert a -> Bool
f -> (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall (f :: * -> *) a b. Applicative f => (a -> b) -> f a -> f b
liftA Bool -> Bool
not a -> Bool
f
    Union a -> Bool
f a -> Bool
g -> (Bool -> Bool -> Bool) -> (a -> Bool) -> (a -> Bool) -> a -> Bool
forall a b c. (a -> b -> c) -> (a -> a) -> (a -> b) -> a -> c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(||) a -> Bool
f a -> Bool
g
    Intersection a -> Bool
f a -> Bool
g -> (Bool -> Bool -> Bool) -> (a -> Bool) -> (a -> Bool) -> a -> Bool
forall a b c. (a -> b -> c) -> (a -> a) -> (a -> b) -> a -> c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) a -> Bool
f a -> Bool
g
    Difference a -> Bool
f a -> Bool
g -> (Bool -> Bool -> Bool) -> (a -> Bool) -> (a -> Bool) -> a -> Bool
forall a b c. (a -> b -> c) -> (a -> a) -> (a -> b) -> a -> c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&~) a -> Bool
f a -> Bool
g
  where
    &&~ :: Bool -> Bool -> Bool
(&&~) Bool
a Bool
b = Bool
a Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
b