hasklepias-0.17.0: src/EventData/Predicates.hs
{-|
Module : Hasklepias Event Type
Description : Defines the Event type and its component types, constructors,
and class instance
Copyright : (c) NoviSci, Inc 2020
License : BSD3
Maintainer : bsaul@novisci.com
-}
{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
-- {-# LANGUAGE Safe #-}
module EventData.Predicates
( isEnrollmentEvent
, isStateFactEvent
, isGenderFactEvent
, isBirthYearEvent
, containsConcepts
, Predicatable(..)
) where
import Data.Bool ( (&&)
, Bool(..)
, (||)
)
import Data.Function ( (.) )
import Data.Functor.Contravariant ( Contravariant(contramap)
, Predicate(..)
)
import Data.Maybe ( Maybe )
import Data.Ord ( Ord )
import Data.Text ( Text )
import EventData.Context ( Concepts
, Context(..)
, Source
, hasConcepts
)
import EventData.Context.Domain ( Domain(..) )
import EventData.Context.Domain.Demographics
import EventData.Core ( Event
, ctxt
)
import IntervalAlgebra ( Interval
, Intervallic(getInterval)
)
{- |
Provides methods for composing predicate functions (i.e. @a -> Bool@) or
'Predicate's by conjunction or disjunction.
-}
class Predicatable a where
(|||) :: a -> a -> a
(&&&) :: a -> a -> a
instance Predicatable (a -> Bool) where
(|||) f g = \x -> f x || g x
(&&&) f g = \x -> f x && g x
instance Predicatable (Predicate a) where
(|||) p1 p2 = Predicate (getPredicate p1 ||| getPredicate p2)
(&&&) p1 p2 = Predicate (getPredicate p1 &&& getPredicate p2)
{- |
Provides a common interface to lift a 'Predicate' on a component of an 'Event'
to a 'Predicate (Event a)'.
-}
class EventPredicate element a where
liftToEventPredicate :: Predicate element -> Predicate (Event a)
instance EventPredicate Context a where
liftToEventPredicate = contramap ctxt
instance EventPredicate Domain a where
liftToEventPredicate = contramap (_facts . ctxt)
instance EventPredicate Concepts a where
liftToEventPredicate = contramap (_concepts . ctxt)
instance EventPredicate (Maybe Source) a where
liftToEventPredicate = contramap (_source . ctxt)
instance (Ord a) => EventPredicate (Interval a) a where
liftToEventPredicate = contramap getInterval
{----------- Predicates -----------------}
-- | Predicate for State facts
isEnrollmentDomain :: Domain -> Bool
isEnrollmentDomain (Enrollment _) = True
isEnrollmentDomain _ = False
-- | Predicate for enrollment events
isEnrollmentEvent :: Predicate (Event a)
isEnrollmentEvent = liftToEventPredicate (Predicate isEnrollmentDomain)
-- | Predicate for Birth Year facts
isBirthYear :: Domain -> Bool
isBirthYear (Demographics (DemographicsFacts (DemographicsInfo BirthYear _))) =
True
isBirthYear _ = False
-- | Predicate for events containing Birth Year facts
isBirthYearEvent :: Predicate (Event a)
isBirthYearEvent = liftToEventPredicate (Predicate isBirthYear)
-- | Predicate for Gender facts
isGenderFact :: Domain -> Bool
isGenderFact (Demographics (DemographicsFacts (DemographicsInfo Gender _))) =
True
isGenderFact _ = False
-- | Predicate for events containing Gender facts
isGenderFactEvent :: Predicate (Event a)
isGenderFactEvent = liftToEventPredicate (Predicate isGenderFact)
-- | Predicate for State facts
isStateFact :: Domain -> Bool
isStateFact (Demographics (DemographicsFacts (DemographicsInfo State _))) =
True
isStateFact _ = False
-- | Predicate for events containing State facts
isStateFactEvent :: Predicate (Event a)
isStateFactEvent = liftToEventPredicate (Predicate isStateFact)
-- | Creates a predicate to check that an 'Event' contains a set of 'EventData.Context.Concept's.
containsConcepts :: [Text] -> Predicate (Event a)
containsConcepts cpt = Predicate (`hasConcepts` cpt)