{-|
Module      : Cohort Index
Description : Defines the Index and related types and functions
Copyright   : (c) NoviSci, Inc 2020
License     : BSD3
Maintainer  : bsaul@novisci.com
-}

-- {-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE DeriveGeneric         #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables   #-}
{-# LANGUAGE TypeApplications      #-}
{-# LANGUAGE FlexibleContexts      #-}

module Hasklepias.AssessmentIntervals
  (
  {- |
The assessment intervals provided are:

* 'Baseline': an interval which either 'IntervalAlgebra.meets' or
  'IntervalAlgebra.precedes' index. Covariates are typically assessed during
  baseline intervals. A cohort's specification may include multiple baseline
  intervals, as different features may require different baseline intervals.
  For example, one feature may use a baseline interval of 365 days prior to
  index, while another uses a baseline interval of 90 days before index up
  to 30 days before index.
* `Followup`: an interval which is 'IntervalAlgebra.startedBy',
  'IntervalAlgebra.metBy', or 'IntervalAlgebra.after' an index. Outcomes
  are typically assessed during followup intervals. Similar to 'Baseline',
    a cohort's specification may include multiple followup intervals,
    as different features may require different followup intervals.

In future versions, one subject may have multiple values for an index
corresponding to unique 'Cohort.Core.ObsUnit'. That is, there is a 1-to-1 map between
index values and observational units, but there may be a 1-to-many map from
subjects to indices.

While users are protected from forming invalid assessment intervals, they still
need to carefully consider how to filter events based on the assessment interval.
Consider the following data:

@
               _      <- Index    (15, 16)
     ----------       <- Baseline (5, 15)
 ---                  <- A (1, 4)
  ---                 <- B (2, 5)
    ---               <- C (4, 7)
      ---             <- D (5, 8)
         ---          <- E (8, 11)
            ---       <- F (12, 15)
              ---     <- G (14, 17)
                 ___  <- H (17, 20)
|----|----|----|----|
0         10        20
@

We have index, baseline, and 8 events (A-H). If Baseline is our assessment interval,
then the events concuring (i.e. not disjoint) with Baseline are C-G.  While C-F
probably make sense to use in deriving some covariate, what about G? The event G
begins during baseline but ends after index. If you want, for example, to know
how many events started during baseline, then you’d want to include G in your
filter (using 'IntervalAlgebra.concur'). But if you wanted to know the durations
of events enclosed by baseline, then you wouldn’t want to filter using concur
and instead perhaps use 'IntervalAlgebra.enclosedBy'.


    -}
    BaselineInterval
  , Baseline(..)
  , FollowupInterval
  , Followup(..)
  , AssessmentInterval
  , makeBaselineMeetsIndex
  , makeBaselineBeforeIndex
  , makeBaselineFinishedByIndex
  , makeFollowupStartedByIndex
  , makeFollowupMetByIndex
  , makeFollowupAfterIndex
  ) where


import           EventDataTheory
import           GHC.Generics    (Generic)
import           Witch

{-| A type to contain baseline intervals. See the 'Baseline' typeclass for methods
to create values of this type.
-}
newtype BaselineInterval a = MkBaselineInterval (Interval a)
  deriving (BaselineInterval a -> BaselineInterval a -> Bool
forall a. Eq a => BaselineInterval a -> BaselineInterval a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BaselineInterval a -> BaselineInterval a -> Bool
$c/= :: forall a. Eq a => BaselineInterval a -> BaselineInterval a -> Bool
== :: BaselineInterval a -> BaselineInterval a -> Bool
$c== :: forall a. Eq a => BaselineInterval a -> BaselineInterval a -> Bool
Eq, Int -> BaselineInterval a -> ShowS
forall a. (Show a, Ord a) => Int -> BaselineInterval a -> ShowS
forall a. (Show a, Ord a) => [BaselineInterval a] -> ShowS
forall a. (Show a, Ord a) => BaselineInterval a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BaselineInterval a] -> ShowS
$cshowList :: forall a. (Show a, Ord a) => [BaselineInterval a] -> ShowS
show :: BaselineInterval a -> String
$cshow :: forall a. (Show a, Ord a) => BaselineInterval a -> String
showsPrec :: Int -> BaselineInterval a -> ShowS
$cshowsPrec :: forall a. (Show a, Ord a) => Int -> BaselineInterval a -> ShowS
Show, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (BaselineInterval a) x -> BaselineInterval a
forall a x. BaselineInterval a -> Rep (BaselineInterval a) x
$cto :: forall a x. Rep (BaselineInterval a) x -> BaselineInterval a
$cfrom :: forall a x. BaselineInterval a -> Rep (BaselineInterval a) x
Generic)

instance Intervallic BaselineInterval  where
  getInterval :: forall a. BaselineInterval a -> Interval a
getInterval (MkBaselineInterval Interval a
x) = forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval Interval a
x
  setInterval :: forall a b. BaselineInterval a -> Interval b -> BaselineInterval b
setInterval (MkBaselineInterval Interval a
x) Interval b
y = forall a. Interval a -> BaselineInterval a
MkBaselineInterval (forall (i :: * -> *) a b. Intervallic i => i a -> Interval b -> i b
setInterval Interval a
x Interval b
y)

{-|
Provides functions for creating a 'BaselineInterval' from an index. The
'baselineMeets' function should satify:

[Meets]

  @'IntervalAlgebra.relate' ('baselineMeets' d i) i = 'IntervalAlgebra.Meets'@

The 'baselineBefore' function should satisfy:

[Before]

  @'IntervalAlgebra.relate' ('baselineBefore' s d i) i = 'IntervalAlgebra.Before'@

The 'baselineFinishedBy' function should satisfy:

[FinishedBy]

  @'IntervalAlgebra.relate' ('baselineFinishedBy' s d i) i = 'IntervalAlgebra.FinishedBy'@

>>> x = (beginerval 1 10)
>>> b =baselineMeets 10 x
>>> b
MkBaselineInterval (0, 10)

>>> relate b x
Meets


>>> x = (beginerval 1 10)
>>> b = baselineBefore 2 4 x
>>> b
MkBaselineInterval (4, 8)

>>> relate b x
Before
-}
class Intervallic i => Baseline i  where
  -- | Creates a 'BaselineInterval' of the given duration that 'IntervalAlgebra.Meets'
  -- the index interval.
  baselineMeets ::
    (SizedIv (Interval a)) =>
    Moment (Interval a) -- ^ duration of baseline
    -> i a -- ^ the index event
    -> BaselineInterval a
  baselineMeets Moment (Interval a)
dur i a
index = forall a. Interval a -> BaselineInterval a
MkBaselineInterval (forall a.
SizedIv (Interval a) =>
Moment (Interval a) -> a -> Interval a
enderval Moment (Interval a)
dur (forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin i a
index))

  -- | Creates a 'BaselineInterval' of the given duration that 'IntervalAlgebra.precedes'
  -- the index interval.
  baselineBefore ::
    (SizedIv (Interval a)) =>
    Moment (Interval a) -- ^ duration to shift back
    -> Moment (Interval a) -- ^ duration of baseline
    -> i a -- ^ the index event
    -> BaselineInterval a
  baselineBefore Moment (Interval a)
shiftBy Moment (Interval a)
dur i a
index =
    forall a. Interval a -> BaselineInterval a
MkBaselineInterval forall a b. (a -> b) -> a -> b
$ forall a.
SizedIv (Interval a) =>
Moment (Interval a) -> a -> Interval a
enderval Moment (Interval a)
dur (forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin (forall a.
SizedIv (Interval a) =>
Moment (Interval a) -> a -> Interval a
enderval Moment (Interval a)
shiftBy (forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin  i a
index)))

  -- | Creates a 'BaselineInterval' of the given duration that 'IntervalAlgebra.FinishedBy'
  -- the index interval.
  baselineFinishedBy ::
    (SizedIv (Interval a), Ord a) =>
    Moment (Interval a) -- ^ duration of baseline - not including the duration of index
    -> i a -- ^ the index event
    -> BaselineInterval a
  baselineFinishedBy Moment (Interval a)
dur i a
index =
    forall a. Interval a -> BaselineInterval a
MkBaselineInterval (forall a (i :: * -> *).
(SizedIv (Interval a), Ord a, Intervallic i) =>
i a -> i a -> Interval a
extenterval (forall a.
SizedIv (Interval a) =>
Moment (Interval a) -> a -> Interval a
enderval Moment (Interval a)
dur (forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin  i a
index)) (forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval  i a
index))

instance Baseline Interval

{-| A type to contain followup intervals. See the 'Followup' typeclass for methods
to create values of this type.
-}
newtype FollowupInterval a = MkFollowupInterval (Interval a)
  deriving (FollowupInterval a -> FollowupInterval a -> Bool
forall a. Eq a => FollowupInterval a -> FollowupInterval a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FollowupInterval a -> FollowupInterval a -> Bool
$c/= :: forall a. Eq a => FollowupInterval a -> FollowupInterval a -> Bool
== :: FollowupInterval a -> FollowupInterval a -> Bool
$c== :: forall a. Eq a => FollowupInterval a -> FollowupInterval a -> Bool
Eq, Int -> FollowupInterval a -> ShowS
forall a. (Show a, Ord a) => Int -> FollowupInterval a -> ShowS
forall a. (Show a, Ord a) => [FollowupInterval a] -> ShowS
forall a. (Show a, Ord a) => FollowupInterval a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FollowupInterval a] -> ShowS
$cshowList :: forall a. (Show a, Ord a) => [FollowupInterval a] -> ShowS
show :: FollowupInterval a -> String
$cshow :: forall a. (Show a, Ord a) => FollowupInterval a -> String
showsPrec :: Int -> FollowupInterval a -> ShowS
$cshowsPrec :: forall a. (Show a, Ord a) => Int -> FollowupInterval a -> ShowS
Show, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (FollowupInterval a) x -> FollowupInterval a
forall a x. FollowupInterval a -> Rep (FollowupInterval a) x
$cto :: forall a x. Rep (FollowupInterval a) x -> FollowupInterval a
$cfrom :: forall a x. FollowupInterval a -> Rep (FollowupInterval a) x
Generic)

instance  Intervallic FollowupInterval where
  getInterval :: forall a. FollowupInterval a -> Interval a
getInterval (MkFollowupInterval Interval a
x) = forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval Interval a
x
  setInterval :: forall a b. FollowupInterval a -> Interval b -> FollowupInterval b
setInterval (MkFollowupInterval Interval a
x) Interval b
y = forall a. Interval a -> FollowupInterval a
MkFollowupInterval (forall (i :: * -> *) a b. Intervallic i => i a -> Interval b -> i b
setInterval Interval a
x Interval b
y)

{-|
Provides functions for creating a 'FollowupInterval' from an index. The
'followup' function should satify:

[StartedBy]

  @'IntervalAlgebra.relate' ('followup' d i) i = 'IntervalAlgebra.StartedBy'@

The 'followupMetBy' function should satisfy:

[MetBy]

  @'IntervalAlgebra.relate' ('followupMetBy' d i) i = 'IntervalAlgebra.MetBy'@

The 'followupAfter' function should satisfy:

[After]

  @'IntervalAlgebra.relate' ('followupAfter' s d i) i = 'IntervalAlgebra.After'@

>>> x = (beginerval 1 10)
>>> f = followup 10 x
>>> f
MkFollowupInterval (10, 20)

>>> relate f x
StartedBy

Note the consequence of providing a duration less than or equal to the duration
of the index: a 'IntervalAlgebra.moment is added to the duration, so that the
end of the 'FollowupInterval' is greater than the end of the index.

>>> x = (beginerval 1 10)
>>> f = followup 1 x
>>> f
MkFollowupInterval (10, 12)

>>> relate f x
StartedBy


>>> x = (beginerval 1 10)
>>> f = followupMetBy 9 x
>>> f
MkFollowupInterval (11, 20)

>>> relate f x
MetBy


>>> x = (beginerval 1 10)
>>> f = followupAfter 1 9 x
>>> f
MkFollowupInterval (12, 21)

>>> relate f x
After

-}
class (Intervallic i)  => Followup i a where
  followup :: (SizedIv (Interval a)
    , Ord (Moment (Interval a)), Num (Moment (Interval a))
    , Intervallic i) =>
    Moment (Interval a) -- ^ duration of followup
    -> i a -- ^ the index event
    -> FollowupInterval a
  followup Moment (Interval a)
dur i a
index = forall a. Interval a -> FollowupInterval a
MkFollowupInterval (forall a.
SizedIv (Interval a) =>
Moment (Interval a) -> a -> Interval a
beginerval Moment (Interval a)
d2 (forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin  i a
index))
    where d2 :: Moment (Interval a)
d2 = if Moment (Interval a)
dur forall a. Ord a => a -> a -> Bool
<= Moment (Interval a)
dindex
                 then Moment (Interval a)
dindex forall a. Num a => a -> a -> a
+ forall iv. SizedIv iv => Moment iv
moment @(Interval a)
                 else Moment (Interval a)
dur
          dindex :: Moment (Interval a)
dindex = forall iv. SizedIv iv => iv -> Moment iv
duration forall a b. (a -> b) -> a -> b
$ forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval i a
index

  followupMetBy ::
    (SizedIv (Interval a)
    , Intervallic i) =>
    Moment (Interval a) -- ^ duration of followup
    -> i a -- ^ the index event
    -> FollowupInterval a
  followupMetBy Moment (Interval a)
dur i a
index = forall a. Interval a -> FollowupInterval a
MkFollowupInterval (forall a.
SizedIv (Interval a) =>
Moment (Interval a) -> a -> Interval a
beginerval Moment (Interval a)
dur (forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end  i a
index))

  followupAfter ::
    (SizedIv (Interval a)
    , Intervallic i) =>
       Moment (Interval a) -- ^ duration add between the end of index and begin of followup
    -> Moment (Interval a) -- ^ duration of followup
    -> i a -- ^ the index event
    -> FollowupInterval a
  followupAfter Moment (Interval a)
shiftBy Moment (Interval a)
dur i a
index =
    forall a. Interval a -> FollowupInterval a
MkFollowupInterval forall a b. (a -> b) -> a -> b
$ forall a.
SizedIv (Interval a) =>
Moment (Interval a) -> a -> Interval a
beginerval Moment (Interval a)
dur (forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end (forall a.
SizedIv (Interval a) =>
Moment (Interval a) -> a -> Interval a
beginerval Moment (Interval a)
shiftBy (forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end  i a
index)))

instance Followup Interval a

-- | A data type that contains variants of intervals during which assessment
-- may occur.
data AssessmentInterval a =
      Bl (BaselineInterval a) -- ^ holds a 'BaselineInterval'
    | Fl (FollowupInterval a) -- ^ holds a 'FollowupInterval'
    deriving (AssessmentInterval a -> AssessmentInterval a -> Bool
forall a.
Eq a =>
AssessmentInterval a -> AssessmentInterval a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AssessmentInterval a -> AssessmentInterval a -> Bool
$c/= :: forall a.
Eq a =>
AssessmentInterval a -> AssessmentInterval a -> Bool
== :: AssessmentInterval a -> AssessmentInterval a -> Bool
$c== :: forall a.
Eq a =>
AssessmentInterval a -> AssessmentInterval a -> Bool
Eq, Int -> AssessmentInterval a -> ShowS
forall a. (Show a, Ord a) => Int -> AssessmentInterval a -> ShowS
forall a. (Show a, Ord a) => [AssessmentInterval a] -> ShowS
forall a. (Show a, Ord a) => AssessmentInterval a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [AssessmentInterval a] -> ShowS
$cshowList :: forall a. (Show a, Ord a) => [AssessmentInterval a] -> ShowS
show :: AssessmentInterval a -> String
$cshow :: forall a. (Show a, Ord a) => AssessmentInterval a -> String
showsPrec :: Int -> AssessmentInterval a -> ShowS
$cshowsPrec :: forall a. (Show a, Ord a) => Int -> AssessmentInterval a -> ShowS
Show, forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (AssessmentInterval a) x -> AssessmentInterval a
forall a x. AssessmentInterval a -> Rep (AssessmentInterval a) x
$cto :: forall a x. Rep (AssessmentInterval a) x -> AssessmentInterval a
$cfrom :: forall a x. AssessmentInterval a -> Rep (AssessmentInterval a) x
Generic)

instance Intervallic AssessmentInterval where
  getInterval :: forall a. AssessmentInterval a -> Interval a
getInterval (Bl BaselineInterval a
x) = forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval BaselineInterval a
x
  getInterval (Fl FollowupInterval a
x) = forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval FollowupInterval a
x

  setInterval :: forall a b.
AssessmentInterval a -> Interval b -> AssessmentInterval b
setInterval (Bl BaselineInterval a
x) Interval b
y = forall a. BaselineInterval a -> AssessmentInterval a
Bl (forall (i :: * -> *) a b. Intervallic i => i a -> Interval b -> i b
setInterval BaselineInterval a
x Interval b
y)
  setInterval (Fl FollowupInterval a
x) Interval b
y = forall a. FollowupInterval a -> AssessmentInterval a
Fl (forall (i :: * -> *) a b. Intervallic i => i a -> Interval b -> i b
setInterval FollowupInterval a
x Interval b
y)

-- | Creates an 'AssessmentInterval' using the 'baseline' function.
--
-- >>> x = beginerval 1 10
-- >>> makeBaselineMeetsIndex 10 x
-- Bl (MkBaselineInterval (0, 10))
--

makeBaselineMeetsIndex
  :: (Baseline i, SizedIv (Interval a)) => Moment (Interval a) -> i a -> AssessmentInterval a
makeBaselineMeetsIndex :: forall (i :: * -> *) a.
(Baseline i, SizedIv (Interval a)) =>
Moment (Interval a) -> i a -> AssessmentInterval a
makeBaselineMeetsIndex Moment (Interval a)
dur i a
index = forall a. BaselineInterval a -> AssessmentInterval a
Bl (forall (i :: * -> *) a.
(Baseline i, SizedIv (Interval a)) =>
Moment (Interval a) -> i a -> BaselineInterval a
baselineMeets Moment (Interval a)
dur i a
index)

-- | Creates an 'AssessmentInterval' using the 'baselineBefore' function.
--
-- >>> x = beginerval 1 10
-- >>> makeBaselineBeforeIndex 2 10 x
-- Bl (MkBaselineInterval (-2, 8))
--
makeBaselineBeforeIndex
  :: (Baseline i, SizedIv (Interval a)) => Moment (Interval a) -> Moment (Interval a) -> i a -> AssessmentInterval a
makeBaselineBeforeIndex :: forall (i :: * -> *) a.
(Baseline i, SizedIv (Interval a)) =>
Moment (Interval a)
-> Moment (Interval a) -> i a -> AssessmentInterval a
makeBaselineBeforeIndex Moment (Interval a)
shiftBy Moment (Interval a)
dur i a
index =
  forall a. BaselineInterval a -> AssessmentInterval a
Bl (forall (i :: * -> *) a.
(Baseline i, SizedIv (Interval a)) =>
Moment (Interval a)
-> Moment (Interval a) -> i a -> BaselineInterval a
baselineBefore Moment (Interval a)
shiftBy Moment (Interval a)
dur i a
index)

-- | Creates an 'AssessmentInterval' using the 'baselineFinishedBy' function.
--
-- >>> x = beginerval 1 10
-- >>> makeBaselineFinishedByIndex 10 x
-- Bl (MkBaselineInterval (0, 11))
--
makeBaselineFinishedByIndex
  :: (Baseline i, SizedIv (Interval a), Ord a) => Moment (Interval a) -> i a -> AssessmentInterval a
makeBaselineFinishedByIndex :: forall (i :: * -> *) a.
(Baseline i, SizedIv (Interval a), Ord a) =>
Moment (Interval a) -> i a -> AssessmentInterval a
makeBaselineFinishedByIndex Moment (Interval a)
dur i a
index = forall a. BaselineInterval a -> AssessmentInterval a
Bl (forall (i :: * -> *) a.
(Baseline i, SizedIv (Interval a), Ord a) =>
Moment (Interval a) -> i a -> BaselineInterval a
baselineFinishedBy Moment (Interval a)
dur i a
index)

-- | Creates an 'AssessmentInterval' using the 'followup' function.
--
-- >>> x = beginerval 1 10
-- >>> makeFollowupStartedByIndex 10 x
-- Fl (MkFollowupInterval (10, 20))
--
makeFollowupStartedByIndex
  :: (Followup i a, SizedIv (Interval a), Ord (Moment (Interval a)), Num (Moment (Interval a))) => Moment (Interval a) -> i a -> AssessmentInterval a
makeFollowupStartedByIndex :: forall (i :: * -> *) a.
(Followup i a, SizedIv (Interval a), Ord (Moment (Interval a)),
 Num (Moment (Interval a))) =>
Moment (Interval a) -> i a -> AssessmentInterval a
makeFollowupStartedByIndex Moment (Interval a)
dur i a
index = forall a. FollowupInterval a -> AssessmentInterval a
Fl (forall (i :: * -> *) a.
(Followup i a, SizedIv (Interval a), Ord (Moment (Interval a)),
 Num (Moment (Interval a)), Intervallic i) =>
Moment (Interval a) -> i a -> FollowupInterval a
followup Moment (Interval a)
dur i a
index)

-- | Creates an 'AssessmentInterval' using the 'followupMetBy' function.
--
-- >>> x = beginerval 1 10
-- >>> makeFollowupMetByIndex 10 x
-- Fl (MkFollowupInterval (11, 21))
--
makeFollowupMetByIndex
  :: (Followup i a, SizedIv (Interval a)) => Moment (Interval a) -> i a -> AssessmentInterval a
makeFollowupMetByIndex :: forall (i :: * -> *) a.
(Followup i a, SizedIv (Interval a)) =>
Moment (Interval a) -> i a -> AssessmentInterval a
makeFollowupMetByIndex Moment (Interval a)
dur i a
index = forall a. FollowupInterval a -> AssessmentInterval a
Fl (forall (i :: * -> *) a.
(Followup i a, SizedIv (Interval a), Intervallic i) =>
Moment (Interval a) -> i a -> FollowupInterval a
followupMetBy Moment (Interval a)
dur i a
index)

-- | Creates an 'AssessmentInterval' using the 'followupAfter' function.
--
-- >>> x = beginerval 1 10
-- >>> makeFollowupAfterIndex 10 10 x
-- Fl (MkFollowupInterval (21, 31))
--
makeFollowupAfterIndex
  :: (Followup i a, SizedIv (Interval a))
  => Moment (Interval a)
  -> Moment (Interval a)
  -> i a
  -> AssessmentInterval a
makeFollowupAfterIndex :: forall (i :: * -> *) a.
(Followup i a, SizedIv (Interval a)) =>
Moment (Interval a)
-> Moment (Interval a) -> i a -> AssessmentInterval a
makeFollowupAfterIndex Moment (Interval a)
shiftBy Moment (Interval a)
dur i a
index = forall a. FollowupInterval a -> AssessmentInterval a
Fl (forall (i :: * -> *) a.
(Followup i a, SizedIv (Interval a), Intervallic i) =>
Moment (Interval a)
-> Moment (Interval a) -> i a -> FollowupInterval a
followupAfter Moment (Interval a)
shiftBy Moment (Interval a)
dur i a
index)