content: module Hydra.Dsl.Compute where
  
  import Hydra.Kernel
  import Hydra.Dsl.Phantoms
  import qualified Hydra.Dsl.Core as Core
  
  import qualified Data.Map as M
  import qualified Data.Maybe as Y
  
  
  adapter :: TTerm Bool -> TTerm t1 -> TTerm t2 -> TTerm (Coder s1 s2 v1 v2) -> TTerm (Adapter s1 s2 t1 t2 v1 v2)
  adapter isLossy source target coder = record _Adapter [
    _Adapter_isLossy>>: isLossy,
    _Adapter_source>>: source,
    _Adapter_target>>: target,
    _Adapter_coder>>: coder]
  
  adapterIsLossy :: TTerm (Adapter s1 s2 t1 t2 v1 v2) -> TTerm Bool
  adapterIsLossy a = project _Adapter _Adapter_isLossy @@ a
  
  adapterSource :: TTerm (Adapter s1 s2 t1 t2 v1 v2) -> TTerm t1
  adapterSource a = project _Adapter _Adapter_source @@ a
  
  adapterTarget :: TTerm (Adapter s1 s2 t1 t2 v1 v2) -> TTerm t2
  adapterTarget a = project _Adapter _Adapter_target @@ a
  
  adapterCoder :: TTerm (Adapter s1 s2 t1 t2 v1 v2) -> TTerm (Coder s1 s2 v1 v2)
  adapterCoder a = project _Adapter _Adapter_coder @@ a
  
  adapterWithCoder :: TTerm (Adapter s1 s2 t1 t2 v1 v2) -> TTerm (Coder s1 s2 v1 v2) -> TTerm (Adapter s1 s2 t1 t2 v1 v2)
  adapterWithCoder a coder = adapter
    (Hydra.Dsl.Compute.adapterIsLossy a)
    (Hydra.Dsl.Compute.adapterSource a)
    (Hydra.Dsl.Compute.adapterTarget a)
    coder
  
  adapterWithTarget :: TTerm (Adapter s1 s2 t1 t2 v1 v2) -> TTerm t2 -> TTerm (Adapter s1 s2 t1 t2 v1 v2)
  adapterWithTarget a target = adapter
    (Hydra.Dsl.Compute.adapterIsLossy a)
    (Hydra.Dsl.Compute.adapterSource a)
    target
    (Hydra.Dsl.Compute.adapterCoder a)
  
  coder :: TTerm (v1 -> Flow s1 v2) -> TTerm (v2 -> Flow s2 v1) -> TTerm (Coder s1 s2 v1 v2)
  coder encode decode = record _Coder [
    _Coder_encode>>: encode,
    _Coder_decode>>: decode]
  
  coderEncode :: TTerm (Coder s1 s2 v1 v2) -> TTerm (v1 -> Flow s1 v2)
  coderEncode c = project _Coder _Coder_encode @@ c
  
  coderDecode :: TTerm (Coder s1 s2 v1 v2) -> TTerm (v2 -> Flow s2 v1)
  coderDecode c = project _Coder _Coder_decode @@ c
  
  flow :: TTerm (s -> Trace -> FlowState s v) -> TTerm (Flow s v)
  flow = wrap _Flow
  
  flowState :: TTerm (Maybe x) -> TTerm s -> TTerm Trace -> TTerm (FlowState s x)
  flowState value state trace = record _FlowState [
    _FlowState_value>>: value,
    _FlowState_state>>: state,
    _FlowState_trace>>: trace]
  
  flowStateState :: TTerm (FlowState s x) -> TTerm s
  flowStateState fs = project _FlowState _FlowState_state @@ fs
  
  flowStateTrace :: TTerm (FlowState s x) -> TTerm Trace
  flowStateTrace fs = project _FlowState _FlowState_trace @@ fs
  
  flowStateValue :: TTerm (FlowState s x) -> TTerm (Maybe x)
  flowStateValue fs = project _FlowState _FlowState_value @@ fs
  
  trace :: TTerm [String] -> TTerm [String] -> TTerm (M.Map Name Term) -> TTerm Trace
  trace stack messages other = record _Trace [
    _Trace_stack>>: stack,
    _Trace_messages>>: messages,
    _Trace_other>>: other]
  
  traceStack :: TTerm Trace -> TTerm [String]
  traceStack t = project _Trace _Trace_stack @@ t
  
  traceMessages :: TTerm Trace -> TTerm [String]
  traceMessages t = project _Trace _Trace_messages @@ t
  
  traceOther :: TTerm Trace -> TTerm (M.Map Name Term)
  traceOther t = project _Trace _Trace_other @@ t
  
  traceWithOther :: TTerm Trace -> TTerm (M.Map Name Term) -> TTerm Trace
  traceWithOther t other = record _Trace [
    _Trace_stack>>: Hydra.Dsl.Compute.traceStack t,
    _Trace_messages>>: Hydra.Dsl.Compute.traceMessages t,
    _Trace_other>>: other]
  
  unFlow :: TTerm (Flow s x) -> TTerm s -> TTerm Trace -> TTerm (FlowState s x)
  unFlow f s t = unwrap _Flow @@ f @@ s @@ t
  