-- | Haskell implementations of hydra/lib/flows primitives

module Hydra.Lib.Flows where

import Hydra.Compute
import qualified Hydra.Tier1 as Tier1

import qualified Control.Monad as CM


-- Haskell-specific helpers

instance Functor (Flow s) where
  fmap :: forall a b. (a -> b) -> Flow s a -> Flow s b
fmap = (a -> b) -> Flow s a -> Flow s b
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
CM.liftM
instance Applicative (Flow s) where
  pure :: forall a. a -> Flow s a
pure = a -> Flow s a
forall a. a -> Flow s a
forall (m :: * -> *) a. Monad m => a -> m a
return
  <*> :: forall a b. Flow s (a -> b) -> Flow s a -> Flow s b
(<*>) = Flow s (a -> b) -> Flow s a -> Flow s b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
CM.ap
instance Monad (Flow s) where
  return :: forall a. a -> Flow s a
return a
x = (s -> Trace -> FlowState s a) -> Flow s a
forall s x. (s -> Trace -> FlowState s x) -> Flow s x
Flow ((s -> Trace -> FlowState s a) -> Flow s a)
-> (s -> Trace -> FlowState s a) -> Flow s a
forall a b. (a -> b) -> a -> b
$ \s
s Trace
t -> Maybe a -> s -> Trace -> FlowState s a
forall s x. Maybe x -> s -> Trace -> FlowState s x
FlowState (a -> Maybe a
forall a. a -> Maybe a
Just a
x) s
s Trace
t
  Flow s a
p >>= :: forall a b. Flow s a -> (a -> Flow s b) -> Flow s b
>>= a -> Flow s b
k = (s -> Trace -> FlowState s b) -> Flow s b
forall s x. (s -> Trace -> FlowState s x) -> Flow s x
Flow s -> Trace -> FlowState s b
q'
    where
      q' :: s -> Trace -> FlowState s b
q' s
s0 Trace
t0 = Maybe b -> s -> Trace -> FlowState s b
forall s x. Maybe x -> s -> Trace -> FlowState s x
FlowState Maybe b
y s
s2 Trace
t2
        where
          FlowState Maybe a
x s
s1 Trace
t1 = Flow s a -> s -> Trace -> FlowState s a
forall s x. Flow s x -> s -> Trace -> FlowState s x
unFlow Flow s a
p s
s0 Trace
t0
          FlowState Maybe b
y s
s2 Trace
t2 = case Maybe a
x of
            Just a
x' -> Flow s b -> s -> Trace -> FlowState s b
forall s x. Flow s x -> s -> Trace -> FlowState s x
unFlow (a -> Flow s b
k a
x') s
s1 Trace
t1
            Maybe a
Nothing -> Maybe b -> s -> Trace -> FlowState s b
forall s x. Maybe x -> s -> Trace -> FlowState s x
FlowState Maybe b
forall a. Maybe a
Nothing s
s1 Trace
t1
instance MonadFail (Flow s) where
  fail :: forall a. String -> Flow s a
fail String
msg = (s -> Trace -> FlowState s a) -> Flow s a
forall s x. (s -> Trace -> FlowState s x) -> Flow s x
Flow ((s -> Trace -> FlowState s a) -> Flow s a)
-> (s -> Trace -> FlowState s a) -> Flow s a
forall a b. (a -> b) -> a -> b
$ \s
s Trace
t -> Maybe a -> s -> Trace -> FlowState s a
forall s x. Maybe x -> s -> Trace -> FlowState s x
FlowState Maybe a
forall a. Maybe a
Nothing s
s (String -> Trace -> Trace
Tier1.pushError String
msg Trace
t)

-- Primitive functions

apply :: Flow s (x -> y) -> Flow s x -> Flow s y
apply :: forall s a b. Flow s (a -> b) -> Flow s a -> Flow s b
apply = Flow s (x -> y) -> Flow s x -> Flow s y
forall a b. Flow s (a -> b) -> Flow s a -> Flow s b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
(<*>)

bind :: Flow s x -> (x -> Flow s y) -> Flow s y
bind :: forall s a b. Flow s a -> (a -> Flow s b) -> Flow s b
bind = Flow s x -> (x -> Flow s y) -> Flow s y
forall a b. Flow s a -> (a -> Flow s b) -> Flow s b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
(>>=)

fail :: String -> Flow s x
fail :: forall s a. String -> Flow s a
fail = String -> Flow s x
forall a. String -> Flow s a
forall (m :: * -> *) a. MonadFail m => String -> m a
CM.fail

map :: (x -> y) -> Flow s x -> Flow s y
map :: forall x y s. (x -> y) -> Flow s x -> Flow s y
map = (x -> y) -> Flow s x -> Flow s y
forall a b. (a -> b) -> Flow s a -> Flow s b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap

mapList :: (x -> Flow s y) -> [x] -> Flow s [y]
mapList :: forall x s y. (x -> Flow s y) -> [x] -> Flow s [y]
mapList = (x -> Flow s y) -> [x] -> Flow s [y]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
CM.mapM

pure :: x -> Flow s x
pure :: forall x s. x -> Flow s x
pure = x -> Flow s x
forall a. a -> Flow s a
forall (m :: * -> *) a. Monad m => a -> m a
return

sequence :: [Flow s x] -> Flow s [x]
sequence :: forall s x. [Flow s x] -> Flow s [x]
sequence = [Flow s x] -> Flow s [x]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
CM.sequence