{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
module Orville.PostgreSQL.Plan
( Plan
, Planned
, Execute
, Explain
, askParam
, execute
, explain
, findMaybeOne
, findMaybeOneWhere
, findOne
, findOneShowVia
, findOneWhere
, findOneWhereShowVia
, findAll
, findAllWhere
, bind
, use
, using
, chain
, chainMaybe
, apply
, planMany
, planList
, focusParam
, planEither
, planMaybe
, Op.AssertionFailed
, assert
, planSelect
, planOperation
)
where
import Control.Exception (throwIO)
import Control.Monad (join)
import qualified Control.Monad.IO.Class as MIO
import Data.Either (partitionEithers)
import qualified Data.List.NonEmpty as NEL
import Orville.PostgreSQL.Execution (Select)
import qualified Orville.PostgreSQL.Expr as Expr
import qualified Orville.PostgreSQL.Marshall as Marshall
import qualified Orville.PostgreSQL.Monad as Monad
import qualified Orville.PostgreSQL.Plan.Explanation as Exp
import Orville.PostgreSQL.Plan.Many (Many)
import qualified Orville.PostgreSQL.Plan.Many as Many
import qualified Orville.PostgreSQL.Plan.Operation as Op
import qualified Orville.PostgreSQL.Schema as Schema
data Plan scope param result where
PlanOp :: Op.Operation param result -> Plan scope param result
PlanMany ::
(forall manyScope. Plan manyScope param result) ->
Plan scope [param] (Many param result)
PlanEither ::
Plan scope leftParam leftResult ->
Plan scope rightParam rightResult ->
Plan scope (Either leftParam rightParam) (Either leftResult rightResult)
Bind ::
Plan scope param a ->
(Planned scope param a -> Plan scope param result) ->
Plan scope param result
Use :: Planned scope param a -> Plan scope param a
Pure :: a -> Plan scope param a
Apply ::
Plan scope param (a -> b) ->
Plan scope param a ->
Plan scope param b
Chain ::
Plan scope a b ->
Plan scope b c ->
Plan scope a c
instance Functor (Plan scope param) where
fmap :: forall a b. (a -> b) -> Plan scope param a -> Plan scope param b
fmap a -> b
f = Plan scope param (a -> b)
-> Plan scope param a -> Plan scope param b
forall scope param a b.
Plan scope param (a -> b)
-> Plan scope param a -> Plan scope param b
Apply ((a -> b) -> Plan scope param (a -> b)
forall a scope param. a -> Plan scope param a
Pure a -> b
f)
instance Applicative (Plan scope param) where
pure :: forall a. a -> Plan scope param a
pure = a -> Plan scope param a
forall a scope param. a -> Plan scope param a
Pure
<*> :: forall a b.
Plan scope param (a -> b)
-> Plan scope param a -> Plan scope param b
(<*>) = Plan scope param (a -> b)
-> Plan scope param a -> Plan scope param b
forall scope param a b.
Plan scope param (a -> b)
-> Plan scope param a -> Plan scope param b
Apply
data Execute
data ExecuteMany
data Planned scope param a where
PlannedOne :: a -> Planned Execute param a
PlannedMany :: Many k a -> Planned ExecuteMany k a
PlannedExplain :: Planned Explain param a
instance Functor (Planned scope param) where
fmap :: forall a b.
(a -> b) -> Planned scope param a -> Planned scope param b
fmap = (a -> b) -> Planned scope param a -> Planned scope param b
forall a b scope param.
(a -> b) -> Planned scope param a -> Planned scope param b
mapPlanned
mapPlanned :: (a -> b) -> Planned scope param a -> Planned scope param b
mapPlanned :: forall a b scope param.
(a -> b) -> Planned scope param a -> Planned scope param b
mapPlanned a -> b
f Planned scope param a
planned =
case Planned scope param a
planned of
PlannedOne a
a ->
b -> Planned Execute param b
forall a param. a -> Planned Execute param a
PlannedOne (a -> b
f a
a)
PlannedMany Many param a
manyAs ->
Many param b -> Planned ExecuteMany param b
forall k a. Many k a -> Planned ExecuteMany k a
PlannedMany ((a -> b) -> Many param a -> Many param b
forall a b. (a -> b) -> Many param a -> Many param b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Many param a
manyAs)
Planned scope param a
PlannedExplain ->
Planned scope param b
Planned Explain param b
forall param a. Planned Explain param a
PlannedExplain
resolveOne :: Planned Execute param a -> a
resolveOne :: forall param a. Planned Execute param a -> a
resolveOne (PlannedOne a
a) = a
a
resolveMany :: Planned ExecuteMany k a -> Many k a
resolveMany :: forall k a. Planned ExecuteMany k a -> Many k a
resolveMany (PlannedMany Many k a
as) = Many k a
as
planOperation ::
Op.Operation param result ->
Plan scope param result
planOperation :: forall param result scope.
Operation param result -> Plan scope param result
planOperation =
Operation param result -> Plan scope param result
forall param result scope.
Operation param result -> Plan scope param result
PlanOp
planSelect :: Select row -> Plan scope () [row]
planSelect :: forall row scope. Select row -> Plan scope () [row]
planSelect Select row
select =
Operation () [row] -> Plan scope () [row]
forall param result scope.
Operation param result -> Plan scope param result
planOperation (Select row -> Operation () [row]
forall param row. Select row -> Operation param [row]
Op.findSelect Select row
select)
askParam :: Plan scope param param
askParam :: forall scope param. Plan scope param param
askParam =
Operation param param -> Plan scope param param
forall param result scope.
Operation param result -> Plan scope param result
planOperation Operation param param
forall param. Operation param param
Op.askParam
findMaybeOne ::
Ord fieldValue =>
Schema.TableDefinition key writeEntity readEntity ->
Marshall.FieldDefinition nullability fieldValue ->
Plan scope fieldValue (Maybe readEntity)
findMaybeOne :: forall fieldValue key writeEntity readEntity nullability scope.
Ord fieldValue =>
TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> Plan scope fieldValue (Maybe readEntity)
findMaybeOne TableDefinition key writeEntity readEntity
tableDef FieldDefinition nullability fieldValue
fieldDef =
Operation fieldValue (Maybe readEntity)
-> Plan scope fieldValue (Maybe readEntity)
forall param result scope.
Operation param result -> Plan scope param result
planOperation (TableDefinition key writeEntity readEntity
-> WherePlanner fieldValue
-> Operation fieldValue (Maybe readEntity)
forall param key writeEntity readEntity.
Ord param =>
TableDefinition key writeEntity readEntity
-> WherePlanner param -> Operation param (Maybe readEntity)
Op.findOne TableDefinition key writeEntity readEntity
tableDef (FieldDefinition nullability fieldValue -> WherePlanner fieldValue
forall fieldValue nullability.
Ord fieldValue =>
FieldDefinition nullability fieldValue -> WherePlanner fieldValue
Op.byField FieldDefinition nullability fieldValue
fieldDef))
findMaybeOneWhere ::
Ord fieldValue =>
Schema.TableDefinition key writeEntity readEntity ->
Marshall.FieldDefinition nullability fieldValue ->
Expr.BooleanExpr ->
Plan scope fieldValue (Maybe readEntity)
findMaybeOneWhere :: forall fieldValue key writeEntity readEntity nullability scope.
Ord fieldValue =>
TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> BooleanExpr
-> Plan scope fieldValue (Maybe readEntity)
findMaybeOneWhere TableDefinition key writeEntity readEntity
tableDef FieldDefinition nullability fieldValue
fieldDef BooleanExpr
cond =
Operation fieldValue (Maybe readEntity)
-> Plan scope fieldValue (Maybe readEntity)
forall param result scope.
Operation param result -> Plan scope param result
planOperation (TableDefinition key writeEntity readEntity
-> WherePlanner fieldValue
-> BooleanExpr
-> Operation fieldValue (Maybe readEntity)
forall param key writeEntity readEntity.
Ord param =>
TableDefinition key writeEntity readEntity
-> WherePlanner param
-> BooleanExpr
-> Operation param (Maybe readEntity)
Op.findOneWhere TableDefinition key writeEntity readEntity
tableDef (FieldDefinition nullability fieldValue -> WherePlanner fieldValue
forall fieldValue nullability.
Ord fieldValue =>
FieldDefinition nullability fieldValue -> WherePlanner fieldValue
Op.byField FieldDefinition nullability fieldValue
fieldDef) BooleanExpr
cond)
findOneShowVia ::
Ord fieldValue =>
(fieldValue -> String) ->
Schema.TableDefinition key writeEntity readEntity ->
Marshall.FieldDefinition nullability fieldValue ->
Plan scope fieldValue readEntity
findOneShowVia :: forall fieldValue key writeEntity readEntity nullability scope.
Ord fieldValue =>
(fieldValue -> String)
-> TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> Plan scope fieldValue readEntity
findOneShowVia fieldValue -> String
showParam TableDefinition key writeEntity readEntity
tableDef FieldDefinition nullability fieldValue
fieldDef =
(fieldValue -> Maybe readEntity -> Either String readEntity)
-> Plan scope fieldValue (Maybe readEntity)
-> Plan scope fieldValue readEntity
forall param a b scope.
(param -> a -> Either String b)
-> Plan scope param a -> Plan scope param b
assert
((fieldValue -> String)
-> TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> fieldValue
-> Maybe readEntity
-> Either String readEntity
forall fieldValue key writeEntity readEntity nullability result.
(fieldValue -> String)
-> TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> fieldValue
-> Maybe result
-> Either String result
assertFound fieldValue -> String
showParam TableDefinition key writeEntity readEntity
tableDef FieldDefinition nullability fieldValue
fieldDef)
(TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> Plan scope fieldValue (Maybe readEntity)
forall fieldValue key writeEntity readEntity nullability scope.
Ord fieldValue =>
TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> Plan scope fieldValue (Maybe readEntity)
findMaybeOne TableDefinition key writeEntity readEntity
tableDef FieldDefinition nullability fieldValue
fieldDef)
findOne ::
(Show fieldValue, Ord fieldValue) =>
Schema.TableDefinition key writeEntity readEntity ->
Marshall.FieldDefinition nullability fieldValue ->
Plan scope fieldValue readEntity
findOne :: forall fieldValue key writeEntity readEntity nullability scope.
(Show fieldValue, Ord fieldValue) =>
TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> Plan scope fieldValue readEntity
findOne = (fieldValue -> String)
-> TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> Plan scope fieldValue readEntity
forall fieldValue key writeEntity readEntity nullability scope.
Ord fieldValue =>
(fieldValue -> String)
-> TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> Plan scope fieldValue readEntity
findOneShowVia fieldValue -> String
forall a. Show a => a -> String
show
findOneWhereShowVia ::
Ord fieldValue =>
(fieldValue -> String) ->
Schema.TableDefinition key writeEntity readEntity ->
Marshall.FieldDefinition nullability fieldValue ->
Expr.BooleanExpr ->
Plan scope fieldValue readEntity
findOneWhereShowVia :: forall fieldValue key writeEntity readEntity nullability scope.
Ord fieldValue =>
(fieldValue -> String)
-> TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> BooleanExpr
-> Plan scope fieldValue readEntity
findOneWhereShowVia fieldValue -> String
showParam TableDefinition key writeEntity readEntity
tableDef FieldDefinition nullability fieldValue
fieldDef BooleanExpr
cond =
(fieldValue -> Maybe readEntity -> Either String readEntity)
-> Plan scope fieldValue (Maybe readEntity)
-> Plan scope fieldValue readEntity
forall param a b scope.
(param -> a -> Either String b)
-> Plan scope param a -> Plan scope param b
assert
((fieldValue -> String)
-> TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> fieldValue
-> Maybe readEntity
-> Either String readEntity
forall fieldValue key writeEntity readEntity nullability result.
(fieldValue -> String)
-> TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> fieldValue
-> Maybe result
-> Either String result
assertFound fieldValue -> String
showParam TableDefinition key writeEntity readEntity
tableDef FieldDefinition nullability fieldValue
fieldDef)
(TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> BooleanExpr
-> Plan scope fieldValue (Maybe readEntity)
forall fieldValue key writeEntity readEntity nullability scope.
Ord fieldValue =>
TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> BooleanExpr
-> Plan scope fieldValue (Maybe readEntity)
findMaybeOneWhere TableDefinition key writeEntity readEntity
tableDef FieldDefinition nullability fieldValue
fieldDef BooleanExpr
cond)
findOneWhere ::
(Show fieldValue, Ord fieldValue) =>
Schema.TableDefinition key writeEntity readEntity ->
Marshall.FieldDefinition nullability fieldValue ->
Expr.BooleanExpr ->
Plan scope fieldValue readEntity
findOneWhere :: forall fieldValue key writeEntity readEntity nullability scope.
(Show fieldValue, Ord fieldValue) =>
TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> BooleanExpr
-> Plan scope fieldValue readEntity
findOneWhere = (fieldValue -> String)
-> TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> BooleanExpr
-> Plan scope fieldValue readEntity
forall fieldValue key writeEntity readEntity nullability scope.
Ord fieldValue =>
(fieldValue -> String)
-> TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> BooleanExpr
-> Plan scope fieldValue readEntity
findOneWhereShowVia fieldValue -> String
forall a. Show a => a -> String
show
assertFound ::
(fieldValue -> String) ->
Schema.TableDefinition key writeEntity readEntity ->
Marshall.FieldDefinition nullability fieldValue ->
fieldValue ->
Maybe result ->
Either String result
assertFound :: forall fieldValue key writeEntity readEntity nullability result.
(fieldValue -> String)
-> TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> fieldValue
-> Maybe result
-> Either String result
assertFound fieldValue -> String
showParam TableDefinition key writeEntity readEntity
tableDef FieldDefinition nullability fieldValue
fieldDef fieldValue
param Maybe result
maybeRecord =
case Maybe result
maybeRecord of
Just result
a ->
result -> Either String result
forall a b. b -> Either a b
Right result
a
Maybe result
Nothing ->
String -> Either String result
forall a b. a -> Either a b
Left (String -> Either String result) -> String -> Either String result
forall a b. (a -> b) -> a -> b
$
[String] -> String
unwords
[ String
"Failed to find record in table "
, TableIdentifier -> String
Schema.tableIdToString (TableIdentifier -> String) -> TableIdentifier -> String
forall a b. (a -> b) -> a -> b
$ TableDefinition key writeEntity readEntity -> TableIdentifier
forall key writeEntity readEntity.
TableDefinition key writeEntity readEntity -> TableIdentifier
Schema.tableIdentifier TableDefinition key writeEntity readEntity
tableDef
, String
" where "
, FieldName -> String
Marshall.fieldNameToString (FieldName -> String) -> FieldName -> String
forall a b. (a -> b) -> a -> b
$ FieldDefinition nullability fieldValue -> FieldName
forall nullability a. FieldDefinition nullability a -> FieldName
Marshall.fieldName FieldDefinition nullability fieldValue
fieldDef
, String
" = "
, fieldValue -> String
showParam fieldValue
param
]
findAll ::
Ord fieldValue =>
Schema.TableDefinition key writeEntity readEntity ->
Marshall.FieldDefinition nullability fieldValue ->
Plan scope fieldValue [readEntity]
findAll :: forall fieldValue key writeEntity readEntity nullability scope.
Ord fieldValue =>
TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> Plan scope fieldValue [readEntity]
findAll TableDefinition key writeEntity readEntity
tableDef FieldDefinition nullability fieldValue
fieldDef =
Operation fieldValue [readEntity]
-> Plan scope fieldValue [readEntity]
forall param result scope.
Operation param result -> Plan scope param result
planOperation (TableDefinition key writeEntity readEntity
-> WherePlanner fieldValue -> Operation fieldValue [readEntity]
forall param key writeEntity readEntity.
Ord param =>
TableDefinition key writeEntity readEntity
-> WherePlanner param -> Operation param [readEntity]
Op.findAll TableDefinition key writeEntity readEntity
tableDef (FieldDefinition nullability fieldValue -> WherePlanner fieldValue
forall fieldValue nullability.
Ord fieldValue =>
FieldDefinition nullability fieldValue -> WherePlanner fieldValue
Op.byField FieldDefinition nullability fieldValue
fieldDef))
findAllWhere ::
Ord fieldValue =>
Schema.TableDefinition key writeEntity readEntity ->
Marshall.FieldDefinition nullability fieldValue ->
Expr.BooleanExpr ->
Plan scope fieldValue [readEntity]
findAllWhere :: forall fieldValue key writeEntity readEntity nullability scope.
Ord fieldValue =>
TableDefinition key writeEntity readEntity
-> FieldDefinition nullability fieldValue
-> BooleanExpr
-> Plan scope fieldValue [readEntity]
findAllWhere TableDefinition key writeEntity readEntity
tableDef FieldDefinition nullability fieldValue
fieldDef BooleanExpr
cond =
Operation fieldValue [readEntity]
-> Plan scope fieldValue [readEntity]
forall param result scope.
Operation param result -> Plan scope param result
planOperation (TableDefinition key writeEntity readEntity
-> WherePlanner fieldValue
-> BooleanExpr
-> Operation fieldValue [readEntity]
forall param key writeEntity readEntity.
Ord param =>
TableDefinition key writeEntity readEntity
-> WherePlanner param
-> BooleanExpr
-> Operation param [readEntity]
Op.findAllWhere TableDefinition key writeEntity readEntity
tableDef (FieldDefinition nullability fieldValue -> WherePlanner fieldValue
forall fieldValue nullability.
Ord fieldValue =>
FieldDefinition nullability fieldValue -> WherePlanner fieldValue
Op.byField FieldDefinition nullability fieldValue
fieldDef) BooleanExpr
cond)
planMany ::
(forall manyScope. Plan manyScope param result) ->
Plan scope [param] (Many param result)
planMany :: forall param result scope.
(forall manyScope. Plan manyScope param result)
-> Plan scope [param] (Many param result)
planMany =
(forall manyScope. Plan manyScope param result)
-> Plan scope [param] (Many param result)
forall param result scope.
(forall manyScope. Plan manyScope param result)
-> Plan scope [param] (Many param result)
PlanMany
planList ::
(forall scope. Plan scope param result) ->
Plan listScope [param] [result]
planList :: forall param result listScope.
(forall scope. Plan scope param result)
-> Plan listScope [param] [result]
planList forall scope. Plan scope param result
plan =
Many param result -> [result]
forall k a. Many k a -> [a]
Many.elems (Many param result -> [result])
-> Plan listScope [param] (Many param result)
-> Plan listScope [param] [result]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (forall scope. Plan scope param result)
-> Plan listScope [param] (Many param result)
forall param result scope.
(forall manyScope. Plan manyScope param result)
-> Plan scope [param] (Many param result)
planMany Plan manyScope param result
forall scope. Plan scope param result
plan
focusParam ::
(a -> b) ->
Plan scope b result ->
Plan scope a result
focusParam :: forall a b scope result.
(a -> b) -> Plan scope b result -> Plan scope a result
focusParam a -> b
focuser Plan scope b result
plan =
Plan scope a b -> Plan scope b result -> Plan scope a result
forall scope a b c.
Plan scope a b -> Plan scope b c -> Plan scope a c
chain (a -> b
focuser (a -> b) -> Plan scope a a -> Plan scope a b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Plan scope a a
forall scope param. Plan scope param param
askParam) Plan scope b result
plan
planEither ::
Plan scope leftParam leftResult ->
Plan scope rightParam rightResult ->
Plan scope (Either leftParam rightParam) (Either leftResult rightResult)
planEither :: forall scope leftParam leftResult rightParam rightResult.
Plan scope leftParam leftResult
-> Plan scope rightParam rightResult
-> Plan
scope (Either leftParam rightParam) (Either leftResult rightResult)
planEither =
Plan scope leftParam leftResult
-> Plan scope rightParam rightResult
-> Plan
scope (Either leftParam rightParam) (Either leftResult rightResult)
forall scope leftParam leftResult rightParam rightResult.
Plan scope leftParam leftResult
-> Plan scope rightParam rightResult
-> Plan
scope (Either leftParam rightParam) (Either leftResult rightResult)
PlanEither
planMaybe :: Plan scope a b -> Plan scope (Maybe a) (Maybe b)
planMaybe :: forall scope a b. Plan scope a b -> Plan scope (Maybe a) (Maybe b)
planMaybe Plan scope a b
plan =
(Maybe a -> Either () a)
-> Plan scope (Either () a) (Maybe b)
-> Plan scope (Maybe a) (Maybe b)
forall a b scope result.
(a -> b) -> Plan scope b result -> Plan scope a result
focusParam (Either () a -> (a -> Either () a) -> Maybe a -> Either () a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (() -> Either () a
forall a b. a -> Either a b
Left ()) a -> Either () a
forall a b. b -> Either a b
Right) (Plan scope (Either () a) (Maybe b)
-> Plan scope (Maybe a) (Maybe b))
-> Plan scope (Either () a) (Maybe b)
-> Plan scope (Maybe a) (Maybe b)
forall a b. (a -> b) -> a -> b
$
(Maybe b -> Maybe b)
-> (Maybe b -> Maybe b) -> Either (Maybe b) (Maybe b) -> Maybe b
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Maybe b -> Maybe b
forall a. a -> a
id Maybe b -> Maybe b
forall a. a -> a
id (Either (Maybe b) (Maybe b) -> Maybe b)
-> Plan scope (Either () a) (Either (Maybe b) (Maybe b))
-> Plan scope (Either () a) (Maybe b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Plan scope () (Maybe b)
-> Plan scope a (Maybe b)
-> Plan scope (Either () a) (Either (Maybe b) (Maybe b))
forall scope leftParam leftResult rightParam rightResult.
Plan scope leftParam leftResult
-> Plan scope rightParam rightResult
-> Plan
scope (Either leftParam rightParam) (Either leftResult rightResult)
planEither (Maybe b -> Plan scope () (Maybe b)
forall a. a -> Plan scope () a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe b
forall a. Maybe a
Nothing) (b -> Maybe b
forall a. a -> Maybe a
Just (b -> Maybe b) -> Plan scope a b -> Plan scope a (Maybe b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Plan scope a b
plan)
bind ::
Plan scope param a ->
(Planned scope param a -> Plan scope param result) ->
Plan scope param result
bind :: forall scope param a result.
Plan scope param a
-> (Planned scope param a -> Plan scope param result)
-> Plan scope param result
bind =
Plan scope param a
-> (Planned scope param a -> Plan scope param result)
-> Plan scope param result
forall scope param a result.
Plan scope param a
-> (Planned scope param a -> Plan scope param result)
-> Plan scope param result
Bind
use :: Planned scope param a -> Plan scope param a
use :: forall scope param a. Planned scope param a -> Plan scope param a
use =
Planned scope param a -> Plan scope param a
forall scope param a. Planned scope param a -> Plan scope param a
Use
using ::
Planned scope param a ->
Plan scope a b ->
Plan scope param b
using :: forall scope param a b.
Planned scope param a -> Plan scope a b -> Plan scope param b
using Planned scope param a
planned Plan scope a b
plan =
Plan scope param a -> Plan scope a b -> Plan scope param b
forall scope a b c.
Plan scope a b -> Plan scope b c -> Plan scope a c
chain (Planned scope param a -> Plan scope param a
forall scope param a. Planned scope param a -> Plan scope param a
use Planned scope param a
planned) Plan scope a b
plan
apply ::
Plan scope param (a -> b) ->
Plan scope param a ->
Plan scope param b
apply :: forall scope param a b.
Plan scope param (a -> b)
-> Plan scope param a -> Plan scope param b
apply =
Plan scope param (a -> b)
-> Plan scope param a -> Plan scope param b
forall scope param a b.
Plan scope param (a -> b)
-> Plan scope param a -> Plan scope param b
Apply
chain ::
Plan scope a b ->
Plan scope b c ->
Plan scope a c
chain :: forall scope a b c.
Plan scope a b -> Plan scope b c -> Plan scope a c
chain =
Plan scope a b -> Plan scope b c -> Plan scope a c
forall scope a b c.
Plan scope a b -> Plan scope b c -> Plan scope a c
Chain
chainMaybe ::
Plan scope a (Maybe b) ->
Plan scope b (Maybe c) ->
Plan scope a (Maybe c)
chainMaybe :: forall scope a b c.
Plan scope a (Maybe b)
-> Plan scope b (Maybe c) -> Plan scope a (Maybe c)
chainMaybe Plan scope a (Maybe b)
a Plan scope b (Maybe c)
b =
let
optionalInput ::
Plan scope a (Maybe b) ->
Plan scope (Maybe a) (Maybe b)
optionalInput :: forall scope a b.
Plan scope a (Maybe b) -> Plan scope (Maybe a) (Maybe b)
optionalInput =
(Maybe (Maybe b) -> Maybe b)
-> Plan scope (Maybe a) (Maybe (Maybe b))
-> Plan scope (Maybe a) (Maybe b)
forall a b.
(a -> b) -> Plan scope (Maybe a) a -> Plan scope (Maybe a) b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe (Maybe b) -> Maybe b
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (Plan scope (Maybe a) (Maybe (Maybe b))
-> Plan scope (Maybe a) (Maybe b))
-> (Plan scope a (Maybe b)
-> Plan scope (Maybe a) (Maybe (Maybe b)))
-> Plan scope a (Maybe b)
-> Plan scope (Maybe a) (Maybe b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Plan scope a (Maybe b) -> Plan scope (Maybe a) (Maybe (Maybe b))
forall scope a b. Plan scope a b -> Plan scope (Maybe a) (Maybe b)
planMaybe
in
Plan scope a (Maybe b)
-> Plan scope (Maybe b) (Maybe c) -> Plan scope a (Maybe c)
forall scope a b c.
Plan scope a b -> Plan scope b c -> Plan scope a c
Chain Plan scope a (Maybe b)
a (Plan scope b (Maybe c) -> Plan scope (Maybe b) (Maybe c)
forall scope a b.
Plan scope a (Maybe b) -> Plan scope (Maybe a) (Maybe b)
optionalInput Plan scope b (Maybe c)
b)
assert ::
(param -> a -> Either String b) ->
Plan scope param a ->
Plan scope param b
assert :: forall param a b scope.
(param -> a -> Either String b)
-> Plan scope param a -> Plan scope param b
assert param -> a -> Either String b
assertion Plan scope param a
aPlan =
let
eitherPlan :: Plan scope param (Either String b)
eitherPlan =
param -> a -> Either String b
assertion
(param -> a -> Either String b)
-> Plan scope param param
-> Plan scope param (a -> Either String b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Plan scope param param
forall scope param. Plan scope param param
askParam
Plan scope param (a -> Either String b)
-> Plan scope param a -> Plan scope param (Either String b)
forall a b.
Plan scope param (a -> b)
-> Plan scope param a -> Plan scope param b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Plan scope param a
aPlan
in
Plan scope param (Either String b)
-> Plan scope (Either String b) b -> Plan scope param b
forall scope a b c.
Plan scope a b -> Plan scope b c -> Plan scope a c
chain Plan scope param (Either String b)
eitherPlan (Operation (Either String b) b -> Plan scope (Either String b) b
forall param result scope.
Operation param result -> Plan scope param result
PlanOp Operation (Either String b) b
forall a. Operation (Either String a) a
Op.assertRight)
execute ::
Monad.MonadOrville m =>
Plan Execute param result ->
param ->
m result
execute :: forall (m :: * -> *) param result.
MonadOrville m =>
Plan Execute param result -> param -> m result
execute Plan Execute param result
plan param
param =
Plan Execute param result -> param -> m result
forall (m :: * -> *) param result.
MonadOrville m =>
Plan Execute param result -> param -> m result
executeOne Plan Execute param result
plan param
param
executeOne ::
Monad.MonadOrville m =>
Plan Execute param result ->
param ->
m result
executeOne :: forall (m :: * -> *) param result.
MonadOrville m =>
Plan Execute param result -> param -> m result
executeOne Plan Execute param result
plan param
param =
case Plan Execute param result
plan of
PlanOp Operation param result
operation -> do
Either AssertionFailed result
opResult <- Operation param result
-> forall (m :: * -> *).
MonadOrville m =>
param -> m (Either AssertionFailed result)
forall param result.
Operation param result
-> forall (m :: * -> *).
MonadOrville m =>
param -> m (Either AssertionFailed result)
Op.executeOperationOne Operation param result
operation param
param
case Either AssertionFailed result
opResult of
Left AssertionFailed
err ->
IO result -> m result
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
MIO.liftIO (AssertionFailed -> IO result
forall e a. Exception e => e -> IO a
throwIO AssertionFailed
err)
Right result
result ->
result -> m result
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure result
result
PlanMany forall manyScope. Plan manyScope param result
manyPlan ->
Plan ExecuteMany param result -> [param] -> m (Many param result)
forall (m :: * -> *) param result.
MonadOrville m =>
Plan ExecuteMany param result -> [param] -> m (Many param result)
executeMany Plan ExecuteMany param result
forall manyScope. Plan manyScope param result
manyPlan param
[param]
param
PlanEither Plan Execute leftParam leftResult
leftPlan Plan Execute rightParam rightResult
rightPlan ->
case param
param of
Left leftParam
leftParam ->
leftResult -> result
leftResult -> Either leftResult rightResult
forall a b. a -> Either a b
Left (leftResult -> result) -> m leftResult -> m result
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Plan Execute leftParam leftResult -> leftParam -> m leftResult
forall (m :: * -> *) param result.
MonadOrville m =>
Plan Execute param result -> param -> m result
executeOne Plan Execute leftParam leftResult
leftPlan leftParam
leftParam
Right rightParam
rightParam ->
rightResult -> result
rightResult -> Either leftResult rightResult
forall a b. b -> Either a b
Right (rightResult -> result) -> m rightResult -> m result
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Plan Execute rightParam rightResult -> rightParam -> m rightResult
forall (m :: * -> *) param result.
MonadOrville m =>
Plan Execute param result -> param -> m result
executeOne Plan Execute rightParam rightResult
rightPlan rightParam
rightParam
Bind Plan Execute param a
intermPlan Planned Execute param a -> Plan Execute param result
continue -> do
a
interm <- Plan Execute param a -> param -> m a
forall (m :: * -> *) param result.
MonadOrville m =>
Plan Execute param result -> param -> m result
executeOne Plan Execute param a
intermPlan param
param
Plan Execute param result -> param -> m result
forall (m :: * -> *) param result.
MonadOrville m =>
Plan Execute param result -> param -> m result
executeOne
(Planned Execute param a -> Plan Execute param result
continue (a -> Planned Execute param a
forall a param. a -> Planned Execute param a
PlannedOne a
interm))
param
param
Use Planned Execute param result
planned ->
result -> m result
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (result -> m result)
-> (Planned Execute param result -> result)
-> Planned Execute param result
-> m result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Planned Execute param result -> result
forall param a. Planned Execute param a -> a
resolveOne (Planned Execute param result -> m result)
-> Planned Execute param result -> m result
forall a b. (a -> b) -> a -> b
$ Planned Execute param result
planned
Pure result
a ->
result -> m result
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure result
a
Apply Plan Execute param (a -> result)
planF Plan Execute param a
planA ->
Plan Execute param (a -> result) -> param -> m (a -> result)
forall (m :: * -> *) param result.
MonadOrville m =>
Plan Execute param result -> param -> m result
executeOne Plan Execute param (a -> result)
planF param
param m (a -> result) -> m a -> m result
forall a b. m (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Plan Execute param a -> param -> m a
forall (m :: * -> *) param result.
MonadOrville m =>
Plan Execute param result -> param -> m result
executeOne Plan Execute param a
planA param
param
Chain Plan Execute param b
planAB Plan Execute b result
planBC -> do
b
b <- Plan Execute param b -> param -> m b
forall (m :: * -> *) param result.
MonadOrville m =>
Plan Execute param result -> param -> m result
executeOne Plan Execute param b
planAB param
param
Plan Execute b result -> b -> m result
forall (m :: * -> *) param result.
MonadOrville m =>
Plan Execute param result -> param -> m result
executeOne Plan Execute b result
planBC b
b
executeMany ::
Monad.MonadOrville m =>
Plan ExecuteMany param result ->
[param] ->
m (Many.Many param result)
executeMany :: forall (m :: * -> *) param result.
MonadOrville m =>
Plan ExecuteMany param result -> [param] -> m (Many param result)
executeMany Plan ExecuteMany param result
plan [param]
params =
case Plan ExecuteMany param result
plan of
PlanOp Operation param result
operation -> do
case [param] -> Maybe (NonEmpty param)
forall a. [a] -> Maybe (NonEmpty a)
NEL.nonEmpty [param]
params of
Maybe (NonEmpty param)
Nothing ->
Many param result -> m (Many param result)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Many param result -> m (Many param result))
-> Many param result -> m (Many param result)
forall a b. (a -> b) -> a -> b
$ [param] -> (param -> Either NotAKey result) -> Many param result
forall k a. [k] -> (k -> Either NotAKey a) -> Many k a
Many.fromKeys [param]
params (Either NotAKey result -> param -> Either NotAKey result
forall a b. a -> b -> a
const (Either NotAKey result -> param -> Either NotAKey result)
-> Either NotAKey result -> param -> Either NotAKey result
forall a b. (a -> b) -> a -> b
$ NotAKey -> Either NotAKey result
forall a b. a -> Either a b
Left NotAKey
Many.NotAKey)
Just NonEmpty param
nonEmptyParams -> do
Either AssertionFailed (Many param result)
opResult <- Operation param result
-> forall (m :: * -> *).
MonadOrville m =>
NonEmpty param -> m (Either AssertionFailed (Many param result))
forall param result.
Operation param result
-> forall (m :: * -> *).
MonadOrville m =>
NonEmpty param -> m (Either AssertionFailed (Many param result))
Op.executeOperationMany Operation param result
operation NonEmpty param
nonEmptyParams
case Either AssertionFailed (Many param result)
opResult of
Left AssertionFailed
err ->
IO (Many param result) -> m (Many param result)
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
MIO.liftIO (AssertionFailed -> IO (Many param result)
forall e a. Exception e => e -> IO a
throwIO AssertionFailed
err)
Right Many param result
results ->
Many param result -> m (Many param result)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Many param result
results
PlanMany forall manyScope. Plan manyScope param result
manyPlan -> do
let
flatParams :: [param]
flatParams = [[param]] -> [param]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [param]
[[param]]
params
Many param result
allResults <- Plan ExecuteMany param result -> [param] -> m (Many param result)
forall (m :: * -> *) param result.
MonadOrville m =>
Plan ExecuteMany param result -> [param] -> m (Many param result)
executeMany Plan ExecuteMany param result
forall manyScope. Plan manyScope param result
manyPlan [param]
flatParams
let
restrictResults :: [param] -> Many param result
restrictResults [param]
subParams =
[param] -> (param -> Either NotAKey result) -> Many param result
forall k a. [k] -> (k -> Either NotAKey a) -> Many k a
Many.fromKeys [param]
subParams (\param
k -> param -> Many param result -> Either NotAKey result
forall k a. k -> Many k a -> Either NotAKey a
Many.lookup param
k Many param result
allResults)
Many param result -> m (Many param result)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Many param result -> m (Many param result))
-> Many param result -> m (Many param result)
forall a b. (a -> b) -> a -> b
$ [param] -> (param -> Either NotAKey result) -> Many param result
forall k a. [k] -> (k -> Either NotAKey a) -> Many k a
Many.fromKeys [param]
params (result -> Either NotAKey result
forall a b. b -> Either a b
Right (result -> Either NotAKey result)
-> (param -> result) -> param -> Either NotAKey result
forall b c a. (b -> c) -> (a -> b) -> a -> c
. param -> result
[param] -> Many param result
restrictResults)
PlanEither Plan ExecuteMany leftParam leftResult
leftPlan Plan ExecuteMany rightParam rightResult
rightPlan -> do
let
([leftParam]
leftParams, [rightParam]
rightParams) = [Either leftParam rightParam] -> ([leftParam], [rightParam])
forall a b. [Either a b] -> ([a], [b])
partitionEithers [param]
[Either leftParam rightParam]
params
Many leftParam leftResult
leftResults <- Plan ExecuteMany leftParam leftResult
-> [leftParam] -> m (Many leftParam leftResult)
forall (m :: * -> *) param result.
MonadOrville m =>
Plan ExecuteMany param result -> [param] -> m (Many param result)
executeMany Plan ExecuteMany leftParam leftResult
leftPlan [leftParam]
leftParams
Many rightParam rightResult
rightResults <- Plan ExecuteMany rightParam rightResult
-> [rightParam] -> m (Many rightParam rightResult)
forall (m :: * -> *) param result.
MonadOrville m =>
Plan ExecuteMany param result -> [param] -> m (Many param result)
executeMany Plan ExecuteMany rightParam rightResult
rightPlan [rightParam]
rightParams
let
eitherResult :: Either leftParam rightParam
-> Either NotAKey (Either leftResult rightResult)
eitherResult Either leftParam rightParam
eitherK =
case Either leftParam rightParam
eitherK of
Left leftParam
k ->
leftResult -> Either leftResult rightResult
forall a b. a -> Either a b
Left (leftResult -> Either leftResult rightResult)
-> Either NotAKey leftResult
-> Either NotAKey (Either leftResult rightResult)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> leftParam -> Many leftParam leftResult -> Either NotAKey leftResult
forall k a. k -> Many k a -> Either NotAKey a
Many.lookup leftParam
k Many leftParam leftResult
leftResults
Right rightParam
k ->
rightResult -> Either leftResult rightResult
forall a b. b -> Either a b
Right (rightResult -> Either leftResult rightResult)
-> Either NotAKey rightResult
-> Either NotAKey (Either leftResult rightResult)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> rightParam
-> Many rightParam rightResult -> Either NotAKey rightResult
forall k a. k -> Many k a -> Either NotAKey a
Many.lookup rightParam
k Many rightParam rightResult
rightResults
Many param result -> m (Many param result)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Many param result -> m (Many param result))
-> Many param result -> m (Many param result)
forall a b. (a -> b) -> a -> b
$ [param] -> (param -> Either NotAKey result) -> Many param result
forall k a. [k] -> (k -> Either NotAKey a) -> Many k a
Many.fromKeys [param]
params param -> Either NotAKey result
Either leftParam rightParam
-> Either NotAKey (Either leftResult rightResult)
eitherResult
Bind Plan ExecuteMany param a
intermPlan Planned ExecuteMany param a -> Plan ExecuteMany param result
continue -> do
Many param a
interms <- Plan ExecuteMany param a -> [param] -> m (Many param a)
forall (m :: * -> *) param result.
MonadOrville m =>
Plan ExecuteMany param result -> [param] -> m (Many param result)
executeMany Plan ExecuteMany param a
intermPlan [param]
params
Plan ExecuteMany param result -> [param] -> m (Many param result)
forall (m :: * -> *) param result.
MonadOrville m =>
Plan ExecuteMany param result -> [param] -> m (Many param result)
executeMany
(Planned ExecuteMany param a -> Plan ExecuteMany param result
continue (Many param a -> Planned ExecuteMany param a
forall k a. Many k a -> Planned ExecuteMany k a
PlannedMany Many param a
interms))
[param]
params
Use Planned ExecuteMany param result
planned ->
Many param result -> m (Many param result)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Many param result -> m (Many param result))
-> (Planned ExecuteMany param result -> Many param result)
-> Planned ExecuteMany param result
-> m (Many param result)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Planned ExecuteMany param result -> Many param result
forall k a. Planned ExecuteMany k a -> Many k a
resolveMany (Planned ExecuteMany param result -> m (Many param result))
-> Planned ExecuteMany param result -> m (Many param result)
forall a b. (a -> b) -> a -> b
$ Planned ExecuteMany param result
planned
Pure result
a ->
Many param result -> m (Many param result)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Many param result -> m (Many param result))
-> Many param result -> m (Many param result)
forall a b. (a -> b) -> a -> b
$ [param] -> (param -> Either NotAKey result) -> Many param result
forall k a. [k] -> (k -> Either NotAKey a) -> Many k a
Many.fromKeys [param]
params (Either NotAKey result -> param -> Either NotAKey result
forall a b. a -> b -> a
const (result -> Either NotAKey result
forall a b. b -> Either a b
Right result
a))
Apply Plan ExecuteMany param (a -> result)
planF Plan ExecuteMany param a
planA -> do
Many param (a -> result)
manyFs <- Plan ExecuteMany param (a -> result)
-> [param] -> m (Many param (a -> result))
forall (m :: * -> *) param result.
MonadOrville m =>
Plan ExecuteMany param result -> [param] -> m (Many param result)
executeMany Plan ExecuteMany param (a -> result)
planF [param]
params
Many param a
manyAs <- Plan ExecuteMany param a -> [param] -> m (Many param a)
forall (m :: * -> *) param result.
MonadOrville m =>
Plan ExecuteMany param result -> [param] -> m (Many param result)
executeMany Plan ExecuteMany param a
planA [param]
params
Many param result -> m (Many param result)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Many param (a -> result) -> Many param a -> Many param result
forall param a b.
Many param (a -> b) -> Many param a -> Many param b
Many.apply Many param (a -> result)
manyFs Many param a
manyAs)
Chain Plan ExecuteMany param b
planAB Plan ExecuteMany b result
planBC -> do
Many param b
bs <- Plan ExecuteMany param b -> [param] -> m (Many param b)
forall (m :: * -> *) param result.
MonadOrville m =>
Plan ExecuteMany param result -> [param] -> m (Many param result)
executeMany Plan ExecuteMany param b
planAB [param]
params
Many b result
cs <- Plan ExecuteMany b result -> [b] -> m (Many b result)
forall (m :: * -> *) param result.
MonadOrville m =>
Plan ExecuteMany param result -> [param] -> m (Many param result)
executeMany Plan ExecuteMany b result
planBC (Many param b -> [b]
forall k a. Many k a -> [a]
Many.elems Many param b
bs)
Many param result -> m (Many param result)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Many param result -> m (Many param result))
-> Many param result -> m (Many param result)
forall a b. (a -> b) -> a -> b
$ Many b result -> Many param b -> Many param result
forall b c a. Many b c -> Many a b -> Many a c
Many.compose Many b result
cs Many param b
bs
data Explain
= ExplainOne
| ExplainMany
explain :: Plan Explain param result -> [String]
explain :: forall param result. Plan Explain param result -> [String]
explain Plan Explain param result
plan =
Explanation -> [String]
Exp.explanationSteps (Explanation -> [String]) -> Explanation -> [String]
forall a b. (a -> b) -> a -> b
$
Explain -> Plan Explain param result -> Explanation
forall param result.
Explain -> Plan Explain param result -> Explanation
explainPlan Explain
ExplainOne Plan Explain param result
plan
explainPlan ::
Explain ->
Plan Explain param result ->
Exp.Explanation
explainPlan :: forall param result.
Explain -> Plan Explain param result -> Explanation
explainPlan Explain
mult Plan Explain param result
plan =
case Plan Explain param result
plan of
PlanOp Operation param result
operation -> do
case Explain
mult of
Explain
ExplainOne ->
Operation param result -> Explanation
forall param result. Operation param result -> Explanation
Op.explainOperationOne Operation param result
operation
Explain
ExplainMany ->
Operation param result -> Explanation
forall param result. Operation param result -> Explanation
Op.explainOperationMany Operation param result
operation
PlanMany forall manyScope. Plan manyScope param result
manyPlan -> do
Explain -> Plan Explain param result -> Explanation
forall param result.
Explain -> Plan Explain param result -> Explanation
explainPlan Explain
ExplainMany Plan Explain param result
forall manyScope. Plan manyScope param result
manyPlan
PlanEither Plan Explain leftParam leftResult
leftPlan Plan Explain rightParam rightResult
rightPlan ->
Explain -> Plan Explain leftParam leftResult -> Explanation
forall param result.
Explain -> Plan Explain param result -> Explanation
explainPlan Explain
mult Plan Explain leftParam leftResult
leftPlan Explanation -> Explanation -> Explanation
forall a. Semigroup a => a -> a -> a
<> Explain -> Plan Explain rightParam rightResult -> Explanation
forall param result.
Explain -> Plan Explain param result -> Explanation
explainPlan Explain
mult Plan Explain rightParam rightResult
rightPlan
Bind Plan Explain param a
intermPlan Planned Explain param a -> Plan Explain param result
continue ->
let
nextPlan :: Plan Explain param result
nextPlan = Planned Explain param a -> Plan Explain param result
continue Planned Explain param a
forall param a. Planned Explain param a
PlannedExplain
in
Explain -> Plan Explain param a -> Explanation
forall param result.
Explain -> Plan Explain param result -> Explanation
explainPlan Explain
mult Plan Explain param a
intermPlan Explanation -> Explanation -> Explanation
forall a. Semigroup a => a -> a -> a
<> Explain -> Plan Explain param result -> Explanation
forall param result.
Explain -> Plan Explain param result -> Explanation
explainPlan Explain
mult Plan Explain param result
nextPlan
Use Planned Explain param result
_ ->
Explanation
Exp.noExplanation
Pure result
_ ->
Explanation
Exp.noExplanation
Apply Plan Explain param (a -> result)
planF Plan Explain param a
planA -> do
Explain -> Plan Explain param (a -> result) -> Explanation
forall param result.
Explain -> Plan Explain param result -> Explanation
explainPlan Explain
mult Plan Explain param (a -> result)
planF Explanation -> Explanation -> Explanation
forall a. Semigroup a => a -> a -> a
<> Explain -> Plan Explain param a -> Explanation
forall param result.
Explain -> Plan Explain param result -> Explanation
explainPlan Explain
mult Plan Explain param a
planA
Chain Plan Explain param b
planAB Plan Explain b result
planBC -> do
Explain -> Plan Explain param b -> Explanation
forall param result.
Explain -> Plan Explain param result -> Explanation
explainPlan Explain
mult Plan Explain param b
planAB Explanation -> Explanation -> Explanation
forall a. Semigroup a => a -> a -> a
<> Explain -> Plan Explain b result -> Explanation
forall param result.
Explain -> Plan Explain param result -> Explanation
explainPlan Explain
mult Plan Explain b result
planBC