{-|
Module      : Stype continuous types
Description : Statistical types
Copyright   : (c) NoviSci, Inc 2020
License     : BSD3
Maintainer  : bsaul@novisci.com

-}

{-# LANGUAGE Safe #-}
{-# LANGUAGE DeriveGeneric #-}

module Stype.Numeric.Continuous (
    Continuous(..)
  , NonnegContinuous(..)
  , EventTime(..)
  , mkEventTime
) where

import safe Control.Applicative           ( Applicative(liftA2) )
import safe GHC.Generics                  ( Generic )

-- | Data type for continuous numbers.
data Continuous a = NegContInf | Cont a | ContInf
  deriving (Continuous a -> Continuous a -> Bool
(Continuous a -> Continuous a -> Bool)
-> (Continuous a -> Continuous a -> Bool) -> Eq (Continuous a)
forall a. Eq a => Continuous a -> Continuous a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Continuous a -> Continuous a -> Bool
$c/= :: forall a. Eq a => Continuous a -> Continuous a -> Bool
== :: Continuous a -> Continuous a -> Bool
$c== :: forall a. Eq a => Continuous a -> Continuous a -> Bool
Eq, Int -> Continuous a -> ShowS
[Continuous a] -> ShowS
Continuous a -> String
(Int -> Continuous a -> ShowS)
-> (Continuous a -> String)
-> ([Continuous a] -> ShowS)
-> Show (Continuous a)
forall a. Show a => Int -> Continuous a -> ShowS
forall a. Show a => [Continuous a] -> ShowS
forall a. Show a => Continuous a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Continuous a] -> ShowS
$cshowList :: forall a. Show a => [Continuous a] -> ShowS
show :: Continuous a -> String
$cshow :: forall a. Show a => Continuous a -> String
showsPrec :: Int -> Continuous a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> Continuous a -> ShowS
Show, Eq (Continuous a)
Eq (Continuous a)
-> (Continuous a -> Continuous a -> Ordering)
-> (Continuous a -> Continuous a -> Bool)
-> (Continuous a -> Continuous a -> Bool)
-> (Continuous a -> Continuous a -> Bool)
-> (Continuous a -> Continuous a -> Bool)
-> (Continuous a -> Continuous a -> Continuous a)
-> (Continuous a -> Continuous a -> Continuous a)
-> Ord (Continuous a)
Continuous a -> Continuous a -> Bool
Continuous a -> Continuous a -> Ordering
Continuous a -> Continuous a -> Continuous a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Continuous a)
forall a. Ord a => Continuous a -> Continuous a -> Bool
forall a. Ord a => Continuous a -> Continuous a -> Ordering
forall a. Ord a => Continuous a -> Continuous a -> Continuous a
min :: Continuous a -> Continuous a -> Continuous a
$cmin :: forall a. Ord a => Continuous a -> Continuous a -> Continuous a
max :: Continuous a -> Continuous a -> Continuous a
$cmax :: forall a. Ord a => Continuous a -> Continuous a -> Continuous a
>= :: Continuous a -> Continuous a -> Bool
$c>= :: forall a. Ord a => Continuous a -> Continuous a -> Bool
> :: Continuous a -> Continuous a -> Bool
$c> :: forall a. Ord a => Continuous a -> Continuous a -> Bool
<= :: Continuous a -> Continuous a -> Bool
$c<= :: forall a. Ord a => Continuous a -> Continuous a -> Bool
< :: Continuous a -> Continuous a -> Bool
$c< :: forall a. Ord a => Continuous a -> Continuous a -> Bool
compare :: Continuous a -> Continuous a -> Ordering
$ccompare :: forall a. Ord a => Continuous a -> Continuous a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (Continuous a)
Ord, (forall x. Continuous a -> Rep (Continuous a) x)
-> (forall x. Rep (Continuous a) x -> Continuous a)
-> Generic (Continuous a)
forall x. Rep (Continuous a) x -> Continuous a
forall x. Continuous a -> Rep (Continuous a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Continuous a) x -> Continuous a
forall a x. Continuous a -> Rep (Continuous a) x
$cto :: forall a x. Rep (Continuous a) x -> Continuous a
$cfrom :: forall a x. Continuous a -> Rep (Continuous a) x
Generic)

instance Functor Continuous where
  fmap :: (a -> b) -> Continuous a -> Continuous b
fmap a -> b
f (Cont a
x) = b -> Continuous b
forall a. a -> Continuous a
Cont (a -> b
f a
x)
  fmap a -> b
f Continuous a
NegContInf = Continuous b
forall a. Continuous a
NegContInf
  fmap a -> b
f Continuous a
ContInf = Continuous b
forall a. Continuous a
ContInf

instance Applicative Continuous where
  pure :: a -> Continuous a
pure a
x = a -> Continuous a
forall a. a -> Continuous a
Cont a
x
  <*> :: Continuous (a -> b) -> Continuous a -> Continuous b
(<*>) (Cont a -> b
f) (Cont a
x) =  b -> Continuous b
forall a. a -> Continuous a
Cont (a -> b
f a
x)
  (<*>) Continuous (a -> b)
NegContInf (Cont a
x) =  Continuous b
forall a. Continuous a
NegContInf
  (<*>) Continuous (a -> b)
ContInf (Cont a
x) =  Continuous b
forall a. Continuous a
ContInf
  (<*>) Continuous (a -> b)
_ Continuous a
NegContInf =  Continuous b
forall a. Continuous a
NegContInf
  (<*>) Continuous (a -> b)
_ Continuous a
ContInf =  Continuous b
forall a. Continuous a
ContInf

instance Num a => Num (Continuous a) where
  + :: Continuous a -> Continuous a -> Continuous a
(+) = (a -> a -> a) -> Continuous a -> Continuous a -> Continuous a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(+)
  * :: Continuous a -> Continuous a -> Continuous a
(*) = (a -> a -> a) -> Continuous a -> Continuous a -> Continuous a
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(*) 
  abs :: Continuous a -> Continuous a
abs = (a -> a) -> Continuous a -> Continuous a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
abs
  fromInteger :: Integer -> Continuous a
fromInteger Integer
x = a -> Continuous a
forall a. a -> Continuous a
Cont (a -> Continuous a) -> a -> Continuous a
forall a b. (a -> b) -> a -> b
$ Integer -> a
forall a. Num a => Integer -> a
fromInteger Integer
x
  signum :: Continuous a -> Continuous a
signum = (a -> a) -> Continuous a -> Continuous a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
signum
  negate :: Continuous a -> Continuous a
negate = (a -> a) -> Continuous a -> Continuous a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
negate

-- | Data type for nonnegative continuous numbers.
data NonnegContinuous a = NonNegCont a | NonNegContInf
  deriving (NonnegContinuous a -> NonnegContinuous a -> Bool
(NonnegContinuous a -> NonnegContinuous a -> Bool)
-> (NonnegContinuous a -> NonnegContinuous a -> Bool)
-> Eq (NonnegContinuous a)
forall a. Eq a => NonnegContinuous a -> NonnegContinuous a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NonnegContinuous a -> NonnegContinuous a -> Bool
$c/= :: forall a. Eq a => NonnegContinuous a -> NonnegContinuous a -> Bool
== :: NonnegContinuous a -> NonnegContinuous a -> Bool
$c== :: forall a. Eq a => NonnegContinuous a -> NonnegContinuous a -> Bool
Eq, Int -> NonnegContinuous a -> ShowS
[NonnegContinuous a] -> ShowS
NonnegContinuous a -> String
(Int -> NonnegContinuous a -> ShowS)
-> (NonnegContinuous a -> String)
-> ([NonnegContinuous a] -> ShowS)
-> Show (NonnegContinuous a)
forall a. Show a => Int -> NonnegContinuous a -> ShowS
forall a. Show a => [NonnegContinuous a] -> ShowS
forall a. Show a => NonnegContinuous a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NonnegContinuous a] -> ShowS
$cshowList :: forall a. Show a => [NonnegContinuous a] -> ShowS
show :: NonnegContinuous a -> String
$cshow :: forall a. Show a => NonnegContinuous a -> String
showsPrec :: Int -> NonnegContinuous a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> NonnegContinuous a -> ShowS
Show, Eq (NonnegContinuous a)
Eq (NonnegContinuous a)
-> (NonnegContinuous a -> NonnegContinuous a -> Ordering)
-> (NonnegContinuous a -> NonnegContinuous a -> Bool)
-> (NonnegContinuous a -> NonnegContinuous a -> Bool)
-> (NonnegContinuous a -> NonnegContinuous a -> Bool)
-> (NonnegContinuous a -> NonnegContinuous a -> Bool)
-> (NonnegContinuous a -> NonnegContinuous a -> NonnegContinuous a)
-> (NonnegContinuous a -> NonnegContinuous a -> NonnegContinuous a)
-> Ord (NonnegContinuous a)
NonnegContinuous a -> NonnegContinuous a -> Bool
NonnegContinuous a -> NonnegContinuous a -> Ordering
NonnegContinuous a -> NonnegContinuous a -> NonnegContinuous a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (NonnegContinuous a)
forall a. Ord a => NonnegContinuous a -> NonnegContinuous a -> Bool
forall a.
Ord a =>
NonnegContinuous a -> NonnegContinuous a -> Ordering
forall a.
Ord a =>
NonnegContinuous a -> NonnegContinuous a -> NonnegContinuous a
min :: NonnegContinuous a -> NonnegContinuous a -> NonnegContinuous a
$cmin :: forall a.
Ord a =>
NonnegContinuous a -> NonnegContinuous a -> NonnegContinuous a
max :: NonnegContinuous a -> NonnegContinuous a -> NonnegContinuous a
$cmax :: forall a.
Ord a =>
NonnegContinuous a -> NonnegContinuous a -> NonnegContinuous a
>= :: NonnegContinuous a -> NonnegContinuous a -> Bool
$c>= :: forall a. Ord a => NonnegContinuous a -> NonnegContinuous a -> Bool
> :: NonnegContinuous a -> NonnegContinuous a -> Bool
$c> :: forall a. Ord a => NonnegContinuous a -> NonnegContinuous a -> Bool
<= :: NonnegContinuous a -> NonnegContinuous a -> Bool
$c<= :: forall a. Ord a => NonnegContinuous a -> NonnegContinuous a -> Bool
< :: NonnegContinuous a -> NonnegContinuous a -> Bool
$c< :: forall a. Ord a => NonnegContinuous a -> NonnegContinuous a -> Bool
compare :: NonnegContinuous a -> NonnegContinuous a -> Ordering
$ccompare :: forall a.
Ord a =>
NonnegContinuous a -> NonnegContinuous a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (NonnegContinuous a)
Ord, (forall x. NonnegContinuous a -> Rep (NonnegContinuous a) x)
-> (forall x. Rep (NonnegContinuous a) x -> NonnegContinuous a)
-> Generic (NonnegContinuous a)
forall x. Rep (NonnegContinuous a) x -> NonnegContinuous a
forall x. NonnegContinuous a -> Rep (NonnegContinuous a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (NonnegContinuous a) x -> NonnegContinuous a
forall a x. NonnegContinuous a -> Rep (NonnegContinuous a) x
$cto :: forall a x. Rep (NonnegContinuous a) x -> NonnegContinuous a
$cfrom :: forall a x. NonnegContinuous a -> Rep (NonnegContinuous a) x
Generic)

data ParseErrorNegative = ParseErrorNegative deriving (ParseErrorNegative -> ParseErrorNegative -> Bool
(ParseErrorNegative -> ParseErrorNegative -> Bool)
-> (ParseErrorNegative -> ParseErrorNegative -> Bool)
-> Eq ParseErrorNegative
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ParseErrorNegative -> ParseErrorNegative -> Bool
$c/= :: ParseErrorNegative -> ParseErrorNegative -> Bool
== :: ParseErrorNegative -> ParseErrorNegative -> Bool
$c== :: ParseErrorNegative -> ParseErrorNegative -> Bool
Eq, Int -> ParseErrorNegative -> ShowS
[ParseErrorNegative] -> ShowS
ParseErrorNegative -> String
(Int -> ParseErrorNegative -> ShowS)
-> (ParseErrorNegative -> String)
-> ([ParseErrorNegative] -> ShowS)
-> Show ParseErrorNegative
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ParseErrorNegative] -> ShowS
$cshowList :: [ParseErrorNegative] -> ShowS
show :: ParseErrorNegative -> String
$cshow :: ParseErrorNegative -> String
showsPrec :: Int -> ParseErrorNegative -> ShowS
$cshowsPrec :: Int -> ParseErrorNegative -> ShowS
Show)

-- | Parse a number into a Nonnegative continuous number.
parseNonnegCont :: (Num a, Ord a) => a -> Either ParseErrorNegative (NonnegContinuous a)
parseNonnegCont :: a -> Either ParseErrorNegative (NonnegContinuous a)
parseNonnegCont a
x 
  | a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0 = ParseErrorNegative
-> Either ParseErrorNegative (NonnegContinuous a)
forall a b. a -> Either a b
Left ParseErrorNegative
ParseErrorNegative
  | Bool
otherwise = NonnegContinuous a
-> Either ParseErrorNegative (NonnegContinuous a)
forall a b. b -> Either a b
Right (a -> NonnegContinuous a
forall a. a -> NonnegContinuous a
NonNegCont a
x)

-- | Data type for event times.
newtype EventTime a = EventTime { EventTime a -> NonnegContinuous a
getEventTime :: NonnegContinuous a }
  deriving (EventTime a -> EventTime a -> Bool
(EventTime a -> EventTime a -> Bool)
-> (EventTime a -> EventTime a -> Bool) -> Eq (EventTime a)
forall a. Eq a => EventTime a -> EventTime a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EventTime a -> EventTime a -> Bool
$c/= :: forall a. Eq a => EventTime a -> EventTime a -> Bool
== :: EventTime a -> EventTime a -> Bool
$c== :: forall a. Eq a => EventTime a -> EventTime a -> Bool
Eq, Int -> EventTime a -> ShowS
[EventTime a] -> ShowS
EventTime a -> String
(Int -> EventTime a -> ShowS)
-> (EventTime a -> String)
-> ([EventTime a] -> ShowS)
-> Show (EventTime a)
forall a. Show a => Int -> EventTime a -> ShowS
forall a. Show a => [EventTime a] -> ShowS
forall a. Show a => EventTime a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EventTime a] -> ShowS
$cshowList :: forall a. Show a => [EventTime a] -> ShowS
show :: EventTime a -> String
$cshow :: forall a. Show a => EventTime a -> String
showsPrec :: Int -> EventTime a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> EventTime a -> ShowS
Show, Eq (EventTime a)
Eq (EventTime a)
-> (EventTime a -> EventTime a -> Ordering)
-> (EventTime a -> EventTime a -> Bool)
-> (EventTime a -> EventTime a -> Bool)
-> (EventTime a -> EventTime a -> Bool)
-> (EventTime a -> EventTime a -> Bool)
-> (EventTime a -> EventTime a -> EventTime a)
-> (EventTime a -> EventTime a -> EventTime a)
-> Ord (EventTime a)
EventTime a -> EventTime a -> Bool
EventTime a -> EventTime a -> Ordering
EventTime a -> EventTime a -> EventTime a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (EventTime a)
forall a. Ord a => EventTime a -> EventTime a -> Bool
forall a. Ord a => EventTime a -> EventTime a -> Ordering
forall a. Ord a => EventTime a -> EventTime a -> EventTime a
min :: EventTime a -> EventTime a -> EventTime a
$cmin :: forall a. Ord a => EventTime a -> EventTime a -> EventTime a
max :: EventTime a -> EventTime a -> EventTime a
$cmax :: forall a. Ord a => EventTime a -> EventTime a -> EventTime a
>= :: EventTime a -> EventTime a -> Bool
$c>= :: forall a. Ord a => EventTime a -> EventTime a -> Bool
> :: EventTime a -> EventTime a -> Bool
$c> :: forall a. Ord a => EventTime a -> EventTime a -> Bool
<= :: EventTime a -> EventTime a -> Bool
$c<= :: forall a. Ord a => EventTime a -> EventTime a -> Bool
< :: EventTime a -> EventTime a -> Bool
$c< :: forall a. Ord a => EventTime a -> EventTime a -> Bool
compare :: EventTime a -> EventTime a -> Ordering
$ccompare :: forall a. Ord a => EventTime a -> EventTime a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (EventTime a)
Ord, (forall x. EventTime a -> Rep (EventTime a) x)
-> (forall x. Rep (EventTime a) x -> EventTime a)
-> Generic (EventTime a)
forall x. Rep (EventTime a) x -> EventTime a
forall x. EventTime a -> Rep (EventTime a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (EventTime a) x -> EventTime a
forall a x. EventTime a -> Rep (EventTime a) x
$cto :: forall a x. Rep (EventTime a) x -> EventTime a
$cfrom :: forall a x. EventTime a -> Rep (EventTime a) x
Generic)

-- | Create an event time from a @Maybe@.
mkEventTime :: Maybe a -> EventTime a
mkEventTime :: Maybe a -> EventTime a
mkEventTime (Just a
x) = NonnegContinuous a -> EventTime a
forall a. NonnegContinuous a -> EventTime a
EventTime (NonnegContinuous a -> EventTime a)
-> NonnegContinuous a -> EventTime a
forall a b. (a -> b) -> a -> b
$ a -> NonnegContinuous a
forall a. a -> NonnegContinuous a
NonNegCont a
x
mkEventTime Maybe a
Nothing  = NonnegContinuous a -> EventTime a
forall a. NonnegContinuous a -> EventTime a
EventTime NonnegContinuous a
forall a. NonnegContinuous a
NonNegContInf