{- |
This module provides functions similar to
"Synthesizer.LLVM.Causal.Process"
but expects functions that operate on 'Value.T'.
This way you can use common arithmetic operators
instead of LLVM assembly functions.
-}
module Synthesizer.LLVM.Causal.ProcessValue (
   map, zipWith, mapAccum, takeWhile,
   ) where

import qualified Synthesizer.LLVM.Causal.Process as Causal
import qualified Synthesizer.LLVM.Simple.Value as Value

import qualified LLVM.Extra.Memory as Memory
import qualified LLVM.Core as LLVM

import Prelude (Bool)


map ::
   (Causal.C process) =>
   (Value.T a -> Value.T b) ->
   process a b
map f =
   Causal.map (Value.unlift1 f)

zipWith ::
   (Causal.C process) =>
   (Value.T a -> Value.T b -> Value.T c) ->
   process (a,b) c
zipWith f =
   Causal.zipWith (Value.unlift2 f)

mapAccum ::
   (Causal.C process, Memory.C s) =>
   (Value.T a -> Value.T s -> (Value.T b, Value.T s)) ->
   Value.T s ->
   process a b
mapAccum next start =
   Causal.mapAccum
      (Value.unlift2 next)
      (Value.unlift0 start)

takeWhile ::
   (Causal.C process) =>
   (Value.T a -> Value.T (LLVM.Value Bool)) ->
   process a a
takeWhile p =
   Causal.takeWhile (Value.unlift1 p)