{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE NoFieldSelectors #-}
module Cauldron
(
Cauldron,
empty,
insert,
adjust,
delete,
keysSet,
restrictKeys,
fromRecipeList,
toRecipeMap,
hoistCauldron,
hoistCauldron',
Recipe (..),
ToRecipe,
fromDecoList,
(Data.Sequence.|>),
(Data.Sequence.<|),
hoistRecipe,
hoistRecipe',
SomeRecipe,
recipe,
withRecipe,
getRecipeCallStack,
Constructor,
val_,
val,
val',
eff_,
ioEff_,
eff,
ioEff,
eff',
wire,
getConstructorArgs,
getConstructorCallStack,
hoistConstructor,
hoistConstructor',
cook,
cookNonEmpty,
cookTree,
Fire,
forbidDepCycles,
allowSelfDeps,
allowDepCycles,
Beans,
taste,
RecipeError (..),
MissingDependencies (..),
DoubleDutyBeans (..),
DependencyCycle (..),
prettyRecipeError,
prettyRecipeErrorLines,
getDependencyGraph,
DependencyGraph,
writeAsDot,
defaultStyle,
setVertexName,
BeanConstructionStep (..),
toAdjacencyMap,
removeSecondaryBeans,
removeDecos,
collapseToPrimaryBeans,
)
where
import Algebra.Graph.AdjacencyMap (AdjacencyMap)
import Algebra.Graph.AdjacencyMap qualified as Graph
import Algebra.Graph.AdjacencyMap.Algorithm qualified as Graph
import Algebra.Graph.Export.Dot qualified as Dot
import Cauldron.Args
import Cauldron.Beans (SomeMonoidTypeRep (..))
import Cauldron.Beans qualified
import Control.Exception (Exception (..))
import Control.Monad.Fix
import Control.Monad.IO.Class
import Data.Bifunctor (first)
import Data.ByteString qualified
import Data.Dynamic
import Data.Foldable qualified
import Data.Function ((&))
import Data.Functor ((<&>))
import Data.Functor.Identity (Identity (..))
import Data.Kind
import Data.List qualified
import Data.List.NonEmpty (NonEmpty)
import Data.List.NonEmpty qualified
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Data.Maybe (fromJust)
import Data.Semigroup qualified
import Data.Sequence (Seq)
import Data.Sequence qualified
import Data.Set (Set)
import Data.Set qualified as Set
import Data.Text qualified
import Data.Text.Encoding qualified
import Data.Tree
import Data.Type.Equality (testEquality)
import Data.Typeable
import GHC.Exception (CallStack, prettyCallStackLines)
import GHC.IsList
import GHC.Stack (HasCallStack, callStack, withFrozenCallStack)
import Type.Reflection qualified
type Cauldron :: (Type -> Type) -> Type
newtype Cauldron m where
Cauldron :: {forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)} -> Cauldron m
empty :: Cauldron m
empty :: forall (m :: * -> *). Cauldron m
empty = Map TypeRep (SomeRecipe m) -> Cauldron m
forall (m :: * -> *). Map TypeRep (SomeRecipe m) -> Cauldron m
Cauldron Map TypeRep (SomeRecipe m)
forall k a. Map k a
Map.empty
instance Semigroup (Cauldron m) where
Cauldron {recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap = Map TypeRep (SomeRecipe m)
r1} <> :: Cauldron m -> Cauldron m -> Cauldron m
<> Cauldron {recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap = Map TypeRep (SomeRecipe m)
r2} = Map TypeRep (SomeRecipe m) -> Cauldron m
forall (m :: * -> *). Map TypeRep (SomeRecipe m) -> Cauldron m
Cauldron do (SomeRecipe m -> SomeRecipe m -> SomeRecipe m)
-> Map TypeRep (SomeRecipe m)
-> Map TypeRep (SomeRecipe m)
-> Map TypeRep (SomeRecipe m)
forall k a. Ord k => (a -> a -> a) -> Map k a -> Map k a -> Map k a
Map.unionWith ((SomeRecipe m -> SomeRecipe m -> SomeRecipe m)
-> SomeRecipe m -> SomeRecipe m -> SomeRecipe m
forall a b c. (a -> b -> c) -> b -> a -> c
flip SomeRecipe m -> SomeRecipe m -> SomeRecipe m
forall a b. a -> b -> a
const) Map TypeRep (SomeRecipe m)
r1 Map TypeRep (SomeRecipe m)
r2
instance Monoid (Cauldron m) where
mempty :: Cauldron m
mempty = Map TypeRep (SomeRecipe m) -> Cauldron m
forall (m :: * -> *). Map TypeRep (SomeRecipe m) -> Cauldron m
Cauldron Map TypeRep (SomeRecipe m)
forall k a. Map k a
Map.empty
instance IsList (Cauldron m) where
type Item (Cauldron m) = SomeRecipe m
toList :: Cauldron m -> [Item (Cauldron m)]
toList (Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap}) = Map TypeRep (SomeRecipe m) -> [SomeRecipe m]
forall k a. Map k a -> [a]
Map.elems Map TypeRep (SomeRecipe m)
recipeMap
fromList :: [Item (Cauldron m)] -> Cauldron m
fromList = [Item (Cauldron m)] -> Cauldron m
[SomeRecipe m] -> Cauldron m
forall (m :: * -> *). [SomeRecipe m] -> Cauldron m
fromRecipeList
hoistCauldron :: (forall x. m x -> n x) -> Cauldron m -> Cauldron n
hoistCauldron :: forall (m :: * -> *) (n :: * -> *).
(forall x. m x -> n x) -> Cauldron m -> Cauldron n
hoistCauldron forall x. m x -> n x
f (Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap}) = Cauldron {recipeMap :: Map TypeRep (SomeRecipe n)
recipeMap = (forall x. m x -> n x) -> SomeRecipe m -> SomeRecipe n
forall (m :: * -> *) (n :: * -> *).
(forall x. m x -> n x) -> SomeRecipe m -> SomeRecipe n
hoistSomeRecipe m x -> n x
forall x. m x -> n x
f (SomeRecipe m -> SomeRecipe n)
-> Map TypeRep (SomeRecipe m) -> Map TypeRep (SomeRecipe n)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map TypeRep (SomeRecipe m)
recipeMap}
hoistCauldron' ::
(forall x. (Typeable x) => Args (m (Regs x)) -> Args (n (Regs x))) ->
(forall x. (Typeable x) => Int -> Args (m (Regs x)) -> Args (n (Regs x))) ->
Cauldron m ->
Cauldron n
hoistCauldron' :: forall (m :: * -> *) (n :: * -> *).
(forall x. Typeable x => Args (m (Regs x)) -> Args (n (Regs x)))
-> (forall x.
Typeable x =>
Int -> Args (m (Regs x)) -> Args (n (Regs x)))
-> Cauldron m
-> Cauldron n
hoistCauldron' forall x. Typeable x => Args (m (Regs x)) -> Args (n (Regs x))
f forall x.
Typeable x =>
Int -> Args (m (Regs x)) -> Args (n (Regs x))
fds Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap} =
Cauldron
{ recipeMap :: Map TypeRep (SomeRecipe n)
recipeMap = (SomeRecipe m -> SomeRecipe n)
-> Map TypeRep (SomeRecipe m) -> Map TypeRep (SomeRecipe n)
forall a b k. (a -> b) -> Map k a -> Map k b
Map.map ((forall x. Typeable x => Args (m (Regs x)) -> Args (n (Regs x)))
-> (forall x.
Typeable x =>
Int -> Args (m (Regs x)) -> Args (n (Regs x)))
-> SomeRecipe m
-> SomeRecipe n
forall (m :: * -> *) (n :: * -> *).
(forall x. Typeable x => Args (m (Regs x)) -> Args (n (Regs x)))
-> (forall x.
Typeable x =>
Int -> Args (m (Regs x)) -> Args (n (Regs x)))
-> SomeRecipe m
-> SomeRecipe n
hoistSomeRecipe' Args (m (Regs x)) -> Args (n (Regs x))
forall x. Typeable x => Args (m (Regs x)) -> Args (n (Regs x))
f Int -> Args (m (Regs x)) -> Args (n (Regs x))
forall x.
Typeable x =>
Int -> Args (m (Regs x)) -> Args (n (Regs x))
fds) Map TypeRep (SomeRecipe m)
recipeMap
}
type SomeRecipe :: (Type -> Type) -> Type
data SomeRecipe m where
SomeRecipe :: (Typeable bean) => {forall (m :: * -> *). SomeRecipe m -> CallStack
_recipeCallStack :: CallStack, ()
_recipe :: Recipe m bean} -> SomeRecipe m
recipe ::
forall {recipelike} {m} bean.
(ToRecipe recipelike, Typeable bean, HasCallStack) =>
recipelike m bean ->
SomeRecipe m
recipe :: forall {recipelike :: (* -> *) -> * -> *} {m :: * -> *} bean.
(ToRecipe recipelike, Typeable bean, HasCallStack) =>
recipelike m bean -> SomeRecipe m
recipe recipelike m bean
theRecipe = (HasCallStack => SomeRecipe m) -> SomeRecipe m
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack do
CallStack -> Recipe m bean -> SomeRecipe m
forall bean (m :: * -> *).
Typeable bean =>
CallStack -> Recipe m bean -> SomeRecipe m
SomeRecipe CallStack
HasCallStack => CallStack
callStack (recipelike m bean -> Recipe m bean
forall (m :: * -> *) bean. recipelike m bean -> Recipe m bean
forall (recipelike :: (* -> *) -> * -> *) (m :: * -> *) bean.
ToRecipe recipelike =>
recipelike m bean -> Recipe m bean
toRecipe recipelike m bean
theRecipe)
withRecipe :: forall {m} r. (forall bean. (Typeable bean) => Recipe m bean -> r) -> SomeRecipe m -> r
withRecipe :: forall {m :: * -> *} r.
(forall bean. Typeable bean => Recipe m bean -> r)
-> SomeRecipe m -> r
withRecipe forall bean. Typeable bean => Recipe m bean -> r
f (SomeRecipe {Recipe m bean
_recipe :: ()
_recipe :: Recipe m bean
_recipe}) = Recipe m bean -> r
forall bean. Typeable bean => Recipe m bean -> r
f Recipe m bean
_recipe
getRecipeRep :: SomeRecipe m -> TypeRep
getRecipeRep :: forall (m :: * -> *). SomeRecipe m -> TypeRep
getRecipeRep = (forall bean. Typeable bean => Recipe m bean -> TypeRep)
-> SomeRecipe m -> TypeRep
forall {m :: * -> *} r.
(forall bean. Typeable bean => Recipe m bean -> r)
-> SomeRecipe m -> r
withRecipe Recipe m bean -> TypeRep
forall bean. Typeable bean => Recipe m bean -> TypeRep
forall bean (m :: * -> *).
Typeable bean =>
Recipe m bean -> TypeRep
go
where
go :: forall bean m. (Typeable bean) => Recipe m bean -> TypeRep
go :: forall bean (m :: * -> *).
Typeable bean =>
Recipe m bean -> TypeRep
go Recipe m bean
_ = Proxy bean -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @bean)
fromRecipeList :: [SomeRecipe m] -> Cauldron m
fromRecipeList :: forall (m :: * -> *). [SomeRecipe m] -> Cauldron m
fromRecipeList =
(SomeRecipe m -> Cauldron m) -> [SomeRecipe m] -> Cauldron m
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap \SomeRecipe m
sr -> Cauldron {recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap = TypeRep -> SomeRecipe m -> Map TypeRep (SomeRecipe m)
forall k a. k -> a -> Map k a
Map.singleton (SomeRecipe m -> TypeRep
forall (m :: * -> *). SomeRecipe m -> TypeRep
getRecipeRep SomeRecipe m
sr) SomeRecipe m
sr}
toRecipeMap :: Cauldron m -> Map TypeRep (SomeRecipe m)
toRecipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
toRecipeMap Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap} = Map TypeRep (SomeRecipe m)
recipeMap
hoistSomeRecipe :: (forall x. m x -> n x) -> SomeRecipe m -> SomeRecipe n
hoistSomeRecipe :: forall (m :: * -> *) (n :: * -> *).
(forall x. m x -> n x) -> SomeRecipe m -> SomeRecipe n
hoistSomeRecipe forall x. m x -> n x
f r :: SomeRecipe m
r@SomeRecipe {Recipe m bean
_recipe :: ()
_recipe :: Recipe m bean
_recipe} = SomeRecipe m
r {_recipe = hoistRecipe f _recipe}
hoistSomeRecipe' ::
forall m n.
(forall x. (Typeable x) => Args (m (Regs x)) -> Args (n (Regs x))) ->
(forall x. (Typeable x) => Int -> Args (m (Regs x)) -> Args (n (Regs x))) ->
SomeRecipe m ->
SomeRecipe n
hoistSomeRecipe' :: forall (m :: * -> *) (n :: * -> *).
(forall x. Typeable x => Args (m (Regs x)) -> Args (n (Regs x)))
-> (forall x.
Typeable x =>
Int -> Args (m (Regs x)) -> Args (n (Regs x)))
-> SomeRecipe m
-> SomeRecipe n
hoistSomeRecipe' forall x. Typeable x => Args (m (Regs x)) -> Args (n (Regs x))
f forall x.
Typeable x =>
Int -> Args (m (Regs x)) -> Args (n (Regs x))
fds SomeRecipe m
sr = (forall bean. Typeable bean => Recipe m bean -> SomeRecipe n)
-> SomeRecipe m -> SomeRecipe n
forall {m :: * -> *} r.
(forall bean. Typeable bean => Recipe m bean -> r)
-> SomeRecipe m -> r
withRecipe Recipe m bean -> SomeRecipe n
forall bean. Typeable bean => Recipe m bean -> SomeRecipe n
go SomeRecipe m
sr
where
go :: forall bean. (Typeable bean) => Recipe m bean -> SomeRecipe n
go :: forall bean. Typeable bean => Recipe m bean -> SomeRecipe n
go Recipe m bean
r = SomeRecipe m
sr {_recipe = hoistRecipe' (f @bean) (fds @bean) r}
type Recipe :: (Type -> Type) -> Type -> Type
data Recipe m bean = Recipe
{
forall (m :: * -> *) bean. Recipe m bean -> Constructor m bean
bean :: Constructor m bean,
forall (m :: * -> *) bean.
Recipe m bean -> Seq (Constructor m bean)
decos :: Seq (Constructor m bean)
}
fromDecoList :: [Constructor m bean] -> Seq (Constructor m bean)
fromDecoList :: forall (m :: * -> *) bean.
[Constructor m bean] -> Seq (Constructor m bean)
fromDecoList = [Constructor m bean] -> Seq (Constructor m bean)
forall a. [a] -> Seq a
Data.Sequence.fromList
type ToRecipe :: ((Type -> Type) -> Type -> Type) -> Constraint
class ToRecipe recipelike where
toRecipe :: recipelike m bean -> Recipe m bean
instance ToRecipe Recipe where
toRecipe :: forall (m :: * -> *) bean. Recipe m bean -> Recipe m bean
toRecipe = Recipe m bean -> Recipe m bean
forall a. a -> a
id
instance ToRecipe Constructor where
toRecipe :: forall (m :: * -> *) bean. Constructor m bean -> Recipe m bean
toRecipe Constructor m bean
bean = Recipe {Constructor m bean
bean :: Constructor m bean
bean :: Constructor m bean
bean, decos :: Seq (Constructor m bean)
decos = Seq (Constructor m bean)
forall a. Seq a
Data.Sequence.empty}
hoistRecipe :: (forall x. m x -> n x) -> Recipe m bean -> Recipe n bean
hoistRecipe :: forall (m :: * -> *) (n :: * -> *) bean.
(forall x. m x -> n x) -> Recipe m bean -> Recipe n bean
hoistRecipe forall x. m x -> n x
f (Recipe {Constructor m bean
bean :: forall (m :: * -> *) bean. Recipe m bean -> Constructor m bean
bean :: Constructor m bean
bean, Seq (Constructor m bean)
decos :: forall (m :: * -> *) bean.
Recipe m bean -> Seq (Constructor m bean)
decos :: Seq (Constructor m bean)
decos}) =
Recipe
{ bean :: Constructor n bean
bean = (forall x. m x -> n x) -> Constructor m bean -> Constructor n bean
forall (m :: * -> *) (n :: * -> *) bean.
(forall x. m x -> n x) -> Constructor m bean -> Constructor n bean
hoistConstructor m x -> n x
forall x. m x -> n x
f Constructor m bean
bean,
decos :: Seq (Constructor n bean)
decos = (forall x. m x -> n x) -> Constructor m bean -> Constructor n bean
forall (m :: * -> *) (n :: * -> *) bean.
(forall x. m x -> n x) -> Constructor m bean -> Constructor n bean
hoistConstructor m x -> n x
forall x. m x -> n x
f (Constructor m bean -> Constructor n bean)
-> Seq (Constructor m bean) -> Seq (Constructor n bean)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Seq (Constructor m bean)
decos
}
hoistRecipe' ::
(Args (m (Regs bean)) -> Args (n (Regs bean))) ->
(Int -> Args (m (Regs bean)) -> Args (n (Regs bean))) ->
Recipe m bean ->
Recipe n bean
hoistRecipe' :: forall (m :: * -> *) bean (n :: * -> *).
(Args (m (Regs bean)) -> Args (n (Regs bean)))
-> (Int -> Args (m (Regs bean)) -> Args (n (Regs bean)))
-> Recipe m bean
-> Recipe n bean
hoistRecipe' Args (m (Regs bean)) -> Args (n (Regs bean))
f Int -> Args (m (Regs bean)) -> Args (n (Regs bean))
fds (Recipe {Constructor m bean
bean :: forall (m :: * -> *) bean. Recipe m bean -> Constructor m bean
bean :: Constructor m bean
bean, Seq (Constructor m bean)
decos :: forall (m :: * -> *) bean.
Recipe m bean -> Seq (Constructor m bean)
decos :: Seq (Constructor m bean)
decos}) =
Recipe
{ bean :: Constructor n bean
bean = (Args (m (Regs bean)) -> Args (n (Regs bean)))
-> Constructor m bean -> Constructor n bean
forall (m :: * -> *) bean (n :: * -> *).
(Args (m (Regs bean)) -> Args (n (Regs bean)))
-> Constructor m bean -> Constructor n bean
hoistConstructor' Args (m (Regs bean)) -> Args (n (Regs bean))
f Constructor m bean
bean,
decos :: Seq (Constructor n bean)
decos = (Int -> Constructor m bean -> Constructor n bean)
-> Seq (Constructor m bean) -> Seq (Constructor n bean)
forall a b. (Int -> a -> b) -> Seq a -> Seq b
Data.Sequence.mapWithIndex (\Int
i Constructor m bean
deco -> (Args (m (Regs bean)) -> Args (n (Regs bean)))
-> Constructor m bean -> Constructor n bean
forall (m :: * -> *) bean (n :: * -> *).
(Args (m (Regs bean)) -> Args (n (Regs bean)))
-> Constructor m bean -> Constructor n bean
hoistConstructor' (Int -> Args (m (Regs bean)) -> Args (n (Regs bean))
fds Int
i) Constructor m bean
deco) Seq (Constructor m bean)
decos
}
data ConstructorReps where
ConstructorReps ::
{ ConstructorReps -> TypeRep
beanRep :: TypeRep,
ConstructorReps -> Set TypeRep
argReps :: Set TypeRep,
ConstructorReps -> Map TypeRep Dynamic
regReps :: Map TypeRep Dynamic
} ->
ConstructorReps
insert ::
forall {recipelike} {m} (bean :: Type).
(Typeable bean, ToRecipe recipelike, HasCallStack) =>
recipelike m bean ->
Cauldron m ->
Cauldron m
insert :: forall {recipelike :: (* -> *) -> * -> *} {m :: * -> *} bean.
(Typeable bean, ToRecipe recipelike, HasCallStack) =>
recipelike m bean -> Cauldron m -> Cauldron m
insert recipelike m bean
recipelike Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap} = (HasCallStack => Cauldron m) -> Cauldron m
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack do
let rep :: TypeRep
rep = Proxy bean -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @bean)
Cauldron {recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap = TypeRep
-> SomeRecipe m
-> Map TypeRep (SomeRecipe m)
-> Map TypeRep (SomeRecipe m)
forall k a. Ord k => k -> a -> Map k a -> Map k a
Map.insert TypeRep
rep (CallStack -> Recipe m bean -> SomeRecipe m
forall bean (m :: * -> *).
Typeable bean =>
CallStack -> Recipe m bean -> SomeRecipe m
SomeRecipe CallStack
HasCallStack => CallStack
callStack (recipelike m bean -> Recipe m bean
forall (m :: * -> *) bean. recipelike m bean -> Recipe m bean
forall (recipelike :: (* -> *) -> * -> *) (m :: * -> *) bean.
ToRecipe recipelike =>
recipelike m bean -> Recipe m bean
toRecipe recipelike m bean
recipelike)) Map TypeRep (SomeRecipe m)
recipeMap}
adjust ::
forall {m} bean.
(Typeable bean) =>
(Recipe m bean -> Recipe m bean) ->
Cauldron m ->
Cauldron m
adjust :: forall {m :: * -> *} bean.
Typeable bean =>
(Recipe m bean -> Recipe m bean) -> Cauldron m -> Cauldron m
adjust Recipe m bean -> Recipe m bean
f (Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap}) = (HasCallStack => Cauldron m) -> Cauldron m
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack do
let rep :: TypeRep
rep = Proxy bean -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @bean)
Cauldron
{ recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap =
Map TypeRep (SomeRecipe m)
recipeMap
Map TypeRep (SomeRecipe m)
-> (Map TypeRep (SomeRecipe m) -> Map TypeRep (SomeRecipe m))
-> Map TypeRep (SomeRecipe m)
forall a b. a -> (a -> b) -> b
& (SomeRecipe m -> SomeRecipe m)
-> TypeRep
-> Map TypeRep (SomeRecipe m)
-> Map TypeRep (SomeRecipe m)
forall k a. Ord k => (a -> a) -> k -> Map k a -> Map k a
Map.adjust
do
\r :: SomeRecipe m
r@SomeRecipe {_recipe :: ()
_recipe = Recipe m bean
_recipe :: Recipe m a} ->
case TypeRep bean -> TypeRep bean -> Maybe (bean :~: bean)
forall a b. TypeRep a -> TypeRep b -> Maybe (a :~: b)
forall {k} (f :: k -> *) (a :: k) (b :: k).
TestEquality f =>
f a -> f b -> Maybe (a :~: b)
testEquality (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
Type.Reflection.typeRep @bean) (forall a. Typeable a => TypeRep a
forall {k} (a :: k). Typeable a => TypeRep a
Type.Reflection.typeRep @a) of
Maybe (bean :~: bean)
Nothing -> String -> SomeRecipe m
forall a. HasCallStack => String -> a
error String
"should never happen"
Just bean :~: bean
Refl -> SomeRecipe m
r {_recipe = f _recipe}
TypeRep
rep
}
delete ::
forall m.
TypeRep ->
Cauldron m ->
Cauldron m
delete :: forall (m :: * -> *). TypeRep -> Cauldron m -> Cauldron m
delete TypeRep
tr Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap} =
Cauldron {recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap = TypeRep -> Map TypeRep (SomeRecipe m) -> Map TypeRep (SomeRecipe m)
forall k a. Ord k => k -> Map k a -> Map k a
Map.delete TypeRep
tr Map TypeRep (SomeRecipe m)
recipeMap}
data Fire m = Fire
{ forall (m :: * -> *).
Fire m -> (BeanConstructionStep, BeanConstructionStep) -> Bool
shouldOmitDependency :: (BeanConstructionStep, BeanConstructionStep) -> Bool,
forall (m :: * -> *).
Fire m -> Cauldron m -> Set TypeRep -> Beans -> Plan -> m Beans
followPlanCauldron ::
Cauldron m ->
Set TypeRep ->
Beans ->
Plan ->
m Beans
}
removeBeanFromArgs :: ConstructorReps -> ConstructorReps
removeBeanFromArgs :: ConstructorReps -> ConstructorReps
removeBeanFromArgs ConstructorReps {Set TypeRep
argReps :: ConstructorReps -> Set TypeRep
argReps :: Set TypeRep
argReps, Map TypeRep Dynamic
regReps :: ConstructorReps -> Map TypeRep Dynamic
regReps :: Map TypeRep Dynamic
regReps, TypeRep
beanRep :: ConstructorReps -> TypeRep
beanRep :: TypeRep
beanRep} =
ConstructorReps {argReps :: Set TypeRep
argReps = TypeRep -> Set TypeRep -> Set TypeRep
forall a. Ord a => a -> Set a -> Set a
Set.delete TypeRep
beanRep Set TypeRep
argReps, Map TypeRep Dynamic
regReps :: Map TypeRep Dynamic
regReps :: Map TypeRep Dynamic
regReps, TypeRep
beanRep :: TypeRep
beanRep :: TypeRep
beanRep}
forbidDepCycles :: (Monad m) => Fire m
forbidDepCycles :: forall (m :: * -> *). Monad m => Fire m
forbidDepCycles =
Fire
{ shouldOmitDependency :: (BeanConstructionStep, BeanConstructionStep) -> Bool
shouldOmitDependency = \(BeanConstructionStep, BeanConstructionStep)
_ -> Bool
False,
followPlanCauldron :: Cauldron m -> Set TypeRep -> Beans -> Plan -> m Beans
followPlanCauldron = \Cauldron m
cauldron Set TypeRep
_secondaryBeanReps Beans
initial Plan
plan ->
(Beans -> BeanConstructionStep -> m Beans)
-> Beans -> Plan -> m Beans
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
Data.Foldable.foldlM
do (TypeRep -> Beans -> Beans)
-> (TypeRep -> Beans -> Beans)
-> Cauldron m
-> Beans
-> Beans
-> BeanConstructionStep
-> m Beans
forall (m :: * -> *).
Monad m =>
(TypeRep -> Beans -> Beans)
-> (TypeRep -> Beans -> Beans)
-> Cauldron m
-> Beans
-> Beans
-> BeanConstructionStep
-> m Beans
followPlanStep (\TypeRep
_ -> Beans -> Beans
forall a. a -> a
id) (\TypeRep
_ -> Beans -> Beans
forall a. a -> a
id) Cauldron m
cauldron Beans
forall a. Monoid a => a
mempty
Beans
initial
Plan
plan
}
allowSelfDeps :: (MonadFix m) => Fire m
allowSelfDeps :: forall (m :: * -> *). MonadFix m => Fire m
allowSelfDeps =
Fire
{ shouldOmitDependency :: (BeanConstructionStep, BeanConstructionStep) -> Bool
shouldOmitDependency = \case
(BarePrimaryBean TypeRep
bean, PrimaryBean TypeRep
anotherBean) | TypeRep
bean TypeRep -> TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
== TypeRep
anotherBean -> Bool
True
(BeanConstructionStep, BeanConstructionStep)
_ -> Bool
False,
followPlanCauldron :: Cauldron m -> Set TypeRep -> Beans -> Plan -> m Beans
followPlanCauldron = \Cauldron m
cauldron Set TypeRep
_secondaryBeanReps Beans
initial Plan
plan ->
(Beans -> m Beans) -> m Beans
forall a. (a -> m a) -> m a
forall (m :: * -> *) a. MonadFix m => (a -> m a) -> m a
mfix do
\Beans
final ->
(Beans -> BeanConstructionStep -> m Beans)
-> Beans -> Plan -> m Beans
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
Data.Foldable.foldlM
do (TypeRep -> Beans -> Beans)
-> (TypeRep -> Beans -> Beans)
-> Cauldron m
-> Beans
-> Beans
-> BeanConstructionStep
-> m Beans
forall (m :: * -> *).
Monad m =>
(TypeRep -> Beans -> Beans)
-> (TypeRep -> Beans -> Beans)
-> Cauldron m
-> Beans
-> Beans
-> BeanConstructionStep
-> m Beans
followPlanStep TypeRep -> Beans -> Beans
Cauldron.Beans.delete (\TypeRep
_ -> Beans -> Beans
forall a. a -> a
id) Cauldron m
cauldron Beans
final
Beans
initial
Plan
plan
}
allowDepCycles :: (MonadFix m) => Fire m
allowDepCycles :: forall (m :: * -> *). MonadFix m => Fire m
allowDepCycles =
Fire
{ shouldOmitDependency :: (BeanConstructionStep, BeanConstructionStep) -> Bool
shouldOmitDependency = \case
(BarePrimaryBean TypeRep
_, PrimaryBean TypeRep
_) -> Bool
True
(PrimaryBeanDeco TypeRep
_ Int
_, PrimaryBean TypeRep
_) -> Bool
True
(BeanConstructionStep, BeanConstructionStep)
_ -> Bool
False,
followPlanCauldron :: Cauldron m -> Set TypeRep -> Beans -> Plan -> m Beans
followPlanCauldron = \Cauldron m
cauldron Set TypeRep
secondaryBeanReps Beans
initial Plan
plan -> do
let makeBareView :: TypeRep -> Beans -> Beans
makeBareView TypeRep
_ = (Beans -> Set TypeRep -> Beans
`Cauldron.Beans.restrictKeys` Set TypeRep
secondaryBeanReps)
let makeDecoView :: TypeRep -> Beans -> Beans
makeDecoView TypeRep
tr = (Beans -> Set TypeRep -> Beans
`Cauldron.Beans.restrictKeys` (TypeRep -> Set TypeRep -> Set TypeRep
forall a. Ord a => a -> Set a -> Set a
Set.insert TypeRep
tr Set TypeRep
secondaryBeanReps))
(Beans -> m Beans) -> m Beans
forall a. (a -> m a) -> m a
forall (m :: * -> *) a. MonadFix m => (a -> m a) -> m a
mfix do
\Beans
final ->
(Beans -> BeanConstructionStep -> m Beans)
-> Beans -> Plan -> m Beans
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
Data.Foldable.foldlM
do (TypeRep -> Beans -> Beans)
-> (TypeRep -> Beans -> Beans)
-> Cauldron m
-> Beans
-> Beans
-> BeanConstructionStep
-> m Beans
forall (m :: * -> *).
Monad m =>
(TypeRep -> Beans -> Beans)
-> (TypeRep -> Beans -> Beans)
-> Cauldron m
-> Beans
-> Beans
-> BeanConstructionStep
-> m Beans
followPlanStep TypeRep -> Beans -> Beans
makeBareView TypeRep -> Beans -> Beans
makeDecoView Cauldron m
cauldron Beans
final
Beans
initial
Plan
plan
}
constructorReps :: forall {m} bean. (Typeable bean) => Constructor m bean -> ConstructorReps
constructorReps :: forall {m :: * -> *} bean.
Typeable bean =>
Constructor m bean -> ConstructorReps
constructorReps (Constructor m bean -> Args (m (Regs bean))
forall (m :: * -> *) bean.
Constructor m bean -> Args (m (Regs bean))
getConstructorArgs -> Args (m (Regs bean))
c) =
ConstructorReps
{ beanRep :: TypeRep
beanRep = Proxy bean -> TypeRep
forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @bean),
argReps :: Set TypeRep
argReps = Args (m (Regs bean)) -> Set TypeRep
forall a. Args a -> Set TypeRep
getArgsReps Args (m (Regs bean))
c,
regReps :: Map TypeRep Dynamic
regReps =
Args (m (Regs bean))
c
Args (m (Regs bean))
-> (Args (m (Regs bean)) -> Set SomeMonoidTypeRep)
-> Set SomeMonoidTypeRep
forall a b. a -> (a -> b) -> b
& Args (m (Regs bean)) -> Set SomeMonoidTypeRep
forall a. Args a -> Set SomeMonoidTypeRep
getRegsReps
Set SomeMonoidTypeRep
-> (Set SomeMonoidTypeRep -> Set (Arg TypeRep Dynamic))
-> Set (Arg TypeRep Dynamic)
forall a b. a -> (a -> b) -> b
& (SomeMonoidTypeRep -> Arg TypeRep Dynamic)
-> Set SomeMonoidTypeRep -> Set (Arg TypeRep Dynamic)
forall b a. Ord b => (a -> b) -> Set a -> Set b
Set.map (\mtr :: SomeMonoidTypeRep
mtr@(SomeMonoidTypeRep TypeRep a
tr) -> TypeRep -> Dynamic -> Arg TypeRep Dynamic
forall a b. a -> b -> Arg a b
Data.Semigroup.Arg (TypeRep a -> TypeRep
forall k (a :: k). TypeRep a -> TypeRep
Type.Reflection.SomeTypeRep TypeRep a
tr) (Dynamic -> Dynamic
forall a. Typeable a => a -> Dynamic
toDyn (SomeMonoidTypeRep -> Dynamic
Cauldron.Beans.someMonoidTypeRepMempty SomeMonoidTypeRep
mtr)))
Set (Arg TypeRep Dynamic)
-> (Set (Arg TypeRep Dynamic) -> Map TypeRep Dynamic)
-> Map TypeRep Dynamic
forall a b. a -> (a -> b) -> b
& Set (Arg TypeRep Dynamic) -> Map TypeRep Dynamic
forall k a. Set (Arg k a) -> Map k a
Map.fromArgSet
}
type Plan = [BeanConstructionStep]
data BeanConstructionStep
=
BarePrimaryBean TypeRep
|
PrimaryBeanDeco TypeRep Int
|
PrimaryBean TypeRep
|
SecondaryBean TypeRep
deriving stock (Int -> BeanConstructionStep -> ShowS
Plan -> ShowS
BeanConstructionStep -> String
(Int -> BeanConstructionStep -> ShowS)
-> (BeanConstructionStep -> String)
-> (Plan -> ShowS)
-> Show BeanConstructionStep
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> BeanConstructionStep -> ShowS
showsPrec :: Int -> BeanConstructionStep -> ShowS
$cshow :: BeanConstructionStep -> String
show :: BeanConstructionStep -> String
$cshowList :: Plan -> ShowS
showList :: Plan -> ShowS
Show, BeanConstructionStep -> BeanConstructionStep -> Bool
(BeanConstructionStep -> BeanConstructionStep -> Bool)
-> (BeanConstructionStep -> BeanConstructionStep -> Bool)
-> Eq BeanConstructionStep
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BeanConstructionStep -> BeanConstructionStep -> Bool
== :: BeanConstructionStep -> BeanConstructionStep -> Bool
$c/= :: BeanConstructionStep -> BeanConstructionStep -> Bool
/= :: BeanConstructionStep -> BeanConstructionStep -> Bool
Eq, Eq BeanConstructionStep
Eq BeanConstructionStep =>
(BeanConstructionStep -> BeanConstructionStep -> Ordering)
-> (BeanConstructionStep -> BeanConstructionStep -> Bool)
-> (BeanConstructionStep -> BeanConstructionStep -> Bool)
-> (BeanConstructionStep -> BeanConstructionStep -> Bool)
-> (BeanConstructionStep -> BeanConstructionStep -> Bool)
-> (BeanConstructionStep
-> BeanConstructionStep -> BeanConstructionStep)
-> (BeanConstructionStep
-> BeanConstructionStep -> BeanConstructionStep)
-> Ord BeanConstructionStep
BeanConstructionStep -> BeanConstructionStep -> Bool
BeanConstructionStep -> BeanConstructionStep -> Ordering
BeanConstructionStep
-> BeanConstructionStep -> BeanConstructionStep
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
$ccompare :: BeanConstructionStep -> BeanConstructionStep -> Ordering
compare :: BeanConstructionStep -> BeanConstructionStep -> Ordering
$c< :: BeanConstructionStep -> BeanConstructionStep -> Bool
< :: BeanConstructionStep -> BeanConstructionStep -> Bool
$c<= :: BeanConstructionStep -> BeanConstructionStep -> Bool
<= :: BeanConstructionStep -> BeanConstructionStep -> Bool
$c> :: BeanConstructionStep -> BeanConstructionStep -> Bool
> :: BeanConstructionStep -> BeanConstructionStep -> Bool
$c>= :: BeanConstructionStep -> BeanConstructionStep -> Bool
>= :: BeanConstructionStep -> BeanConstructionStep -> Bool
$cmax :: BeanConstructionStep
-> BeanConstructionStep -> BeanConstructionStep
max :: BeanConstructionStep
-> BeanConstructionStep -> BeanConstructionStep
$cmin :: BeanConstructionStep
-> BeanConstructionStep -> BeanConstructionStep
min :: BeanConstructionStep
-> BeanConstructionStep -> BeanConstructionStep
Ord)
cook ::
forall m.
(Monad m) =>
Fire m ->
Cauldron m ->
Either RecipeError (m Beans)
cook :: forall (m :: * -> *).
Monad m =>
Fire m -> Cauldron m -> Either RecipeError (m Beans)
cook Fire m
fire Cauldron m
cauldron =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap @(Either RecipeError) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap @m Tree Beans -> Beans
forall a. Tree a -> a
rootLabel) (Either RecipeError (m (Tree Beans))
-> Either RecipeError (m Beans))
-> Either RecipeError (m (Tree Beans))
-> Either RecipeError (m Beans)
forall a b. (a -> b) -> a -> b
$
Tree (Fire m, Cauldron m) -> Either RecipeError (m (Tree Beans))
forall (m :: * -> *).
Monad m =>
Tree (Fire m, Cauldron m) -> Either RecipeError (m (Tree Beans))
cookTree ((Fire m, Cauldron m)
-> [Tree (Fire m, Cauldron m)] -> Tree (Fire m, Cauldron m)
forall a. a -> [Tree a] -> Tree a
Node (Fire m
fire, Cauldron m
cauldron) [])
cookNonEmpty ::
forall m.
(Monad m) =>
NonEmpty (Fire m, Cauldron m) ->
Either RecipeError (m (NonEmpty Beans))
cookNonEmpty :: forall (m :: * -> *).
Monad m =>
NonEmpty (Fire m, Cauldron m)
-> Either RecipeError (m (NonEmpty Beans))
cookNonEmpty NonEmpty (Fire m, Cauldron m)
nonemptyCauldronList = do
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap @(Either RecipeError) (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap @m Tree Beans -> NonEmpty Beans
forall a. Tree a -> NonEmpty a
unsafeTreeToNonEmpty) (Either RecipeError (m (Tree Beans))
-> Either RecipeError (m (NonEmpty Beans)))
-> Either RecipeError (m (Tree Beans))
-> Either RecipeError (m (NonEmpty Beans))
forall a b. (a -> b) -> a -> b
$
Tree (Fire m, Cauldron m) -> Either RecipeError (m (Tree Beans))
forall (m :: * -> *).
Monad m =>
Tree (Fire m, Cauldron m) -> Either RecipeError (m (Tree Beans))
cookTree (NonEmpty (Fire m, Cauldron m) -> Tree (Fire m, Cauldron m)
forall a. NonEmpty a -> Tree a
nonEmptyToTree NonEmpty (Fire m, Cauldron m)
nonemptyCauldronList)
cookTree ::
forall m.
(Monad m) =>
Tree (Fire m, Cauldron m) ->
Either RecipeError (m (Tree Beans))
cookTree :: forall (m :: * -> *).
Monad m =>
Tree (Fire m, Cauldron m) -> Either RecipeError (m (Tree Beans))
cookTree (Tree (Fire m, Cauldron m)
treecipes) = do
accumMap <- (DoubleDutyBeans -> RecipeError)
-> Either DoubleDutyBeans (Map TypeRep Dynamic)
-> Either RecipeError (Map TypeRep Dynamic)
forall a b c. (a -> b) -> Either a c -> Either b c
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first DoubleDutyBeans -> RecipeError
DoubleDutyBeansError do Tree (Cauldron m) -> Either DoubleDutyBeans (Map TypeRep Dynamic)
forall (m :: * -> *).
Tree (Cauldron m) -> Either DoubleDutyBeans (Map TypeRep Dynamic)
checkNoDoubleDutyBeans ((Fire m, Cauldron m) -> Cauldron m
forall a b. (a, b) -> b
snd ((Fire m, Cauldron m) -> Cauldron m)
-> Tree (Fire m, Cauldron m) -> Tree (Cauldron m)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Tree (Fire m, Cauldron m)
treecipes)
() <- first MissingDependenciesError do checkMissingDeps (Map.keysSet accumMap) (snd <$> treecipes)
treeplan <- first DependencyCycleError do buildPlans (Map.keysSet accumMap) treecipes
Right $ followPlan (fromDynList (Data.Foldable.toList accumMap)) (treeplan)
newtype DoubleDutyBeans = DoubleDutyBeans (Map TypeRep (CallStack, CallStack))
deriving stock (Int -> DoubleDutyBeans -> ShowS
[DoubleDutyBeans] -> ShowS
DoubleDutyBeans -> String
(Int -> DoubleDutyBeans -> ShowS)
-> (DoubleDutyBeans -> String)
-> ([DoubleDutyBeans] -> ShowS)
-> Show DoubleDutyBeans
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DoubleDutyBeans -> ShowS
showsPrec :: Int -> DoubleDutyBeans -> ShowS
$cshow :: DoubleDutyBeans -> String
show :: DoubleDutyBeans -> String
$cshowList :: [DoubleDutyBeans] -> ShowS
showList :: [DoubleDutyBeans] -> ShowS
Show)
getDependencyGraph :: Cauldron m -> DependencyGraph
getDependencyGraph :: forall (m :: * -> *). Cauldron m -> DependencyGraph
getDependencyGraph Cauldron m
cauldron =
let (Map TypeRep (CallStack, Dynamic)
accumMap, Map TypeRep CallStack
_) = Cauldron m
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
forall (m :: * -> *).
Cauldron m
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
cauldronRegs Cauldron m
cauldron
(Map BeanConstructionStep CallStack
_, [(BeanConstructionStep, BeanConstructionStep)]
deps) = Set TypeRep
-> Cauldron m
-> (Map BeanConstructionStep CallStack,
[(BeanConstructionStep, BeanConstructionStep)])
forall (m :: * -> *).
Set TypeRep
-> Cauldron m
-> (Map BeanConstructionStep CallStack,
[(BeanConstructionStep, BeanConstructionStep)])
buildDepsCauldron (Map TypeRep (CallStack, Dynamic) -> Set TypeRep
forall k a. Map k a -> Set k
Map.keysSet Map TypeRep (CallStack, Dynamic)
accumMap) Cauldron m
cauldron
in DependencyGraph {graph :: AdjacencyMap BeanConstructionStep
graph = [(BeanConstructionStep, BeanConstructionStep)]
-> AdjacencyMap BeanConstructionStep
forall a. Ord a => [(a, a)] -> AdjacencyMap a
Graph.edges [(BeanConstructionStep, BeanConstructionStep)]
deps}
checkNoDoubleDutyBeans ::
Tree (Cauldron m) ->
Either DoubleDutyBeans (Map TypeRep Dynamic)
checkNoDoubleDutyBeans :: forall (m :: * -> *).
Tree (Cauldron m) -> Either DoubleDutyBeans (Map TypeRep Dynamic)
checkNoDoubleDutyBeans Tree (Cauldron m)
treecipes = do
let (Map TypeRep (CallStack, Dynamic)
accumMap, Map TypeRep CallStack
beanSet) = Tree (Cauldron m)
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
forall (m :: * -> *).
Tree (Cauldron m)
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
cauldronTreeRegs Tree (Cauldron m)
treecipes
let common :: Map TypeRep (CallStack, CallStack)
common = (CallStack -> CallStack -> (CallStack, CallStack))
-> Map TypeRep CallStack
-> Map TypeRep CallStack
-> Map TypeRep (CallStack, CallStack)
forall k a b c.
Ord k =>
(a -> b -> c) -> Map k a -> Map k b -> Map k c
Map.intersectionWith (,) ((CallStack, Dynamic) -> CallStack
forall a b. (a, b) -> a
fst ((CallStack, Dynamic) -> CallStack)
-> Map TypeRep (CallStack, Dynamic) -> Map TypeRep CallStack
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map TypeRep (CallStack, Dynamic)
accumMap) Map TypeRep CallStack
beanSet
if Bool -> Bool
not (Map TypeRep (CallStack, CallStack) -> Bool
forall k a. Map k a -> Bool
Map.null Map TypeRep (CallStack, CallStack)
common)
then DoubleDutyBeans -> Either DoubleDutyBeans (Map TypeRep Dynamic)
forall a b. a -> Either a b
Left (DoubleDutyBeans -> Either DoubleDutyBeans (Map TypeRep Dynamic))
-> DoubleDutyBeans -> Either DoubleDutyBeans (Map TypeRep Dynamic)
forall a b. (a -> b) -> a -> b
$ Map TypeRep (CallStack, CallStack) -> DoubleDutyBeans
DoubleDutyBeans Map TypeRep (CallStack, CallStack)
common
else Map TypeRep Dynamic -> Either DoubleDutyBeans (Map TypeRep Dynamic)
forall a b. b -> Either a b
Right (Map TypeRep Dynamic
-> Either DoubleDutyBeans (Map TypeRep Dynamic))
-> Map TypeRep Dynamic
-> Either DoubleDutyBeans (Map TypeRep Dynamic)
forall a b. (a -> b) -> a -> b
$ (CallStack, Dynamic) -> Dynamic
forall a b. (a, b) -> b
snd ((CallStack, Dynamic) -> Dynamic)
-> Map TypeRep (CallStack, Dynamic) -> Map TypeRep Dynamic
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Map TypeRep (CallStack, Dynamic)
accumMap
cauldronTreeRegs :: Tree (Cauldron m) -> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
cauldronTreeRegs :: forall (m :: * -> *).
Tree (Cauldron m)
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
cauldronTreeRegs = (Cauldron m
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack))
-> Tree (Cauldron m)
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
forall m a. Monoid m => (a -> m) -> Tree a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Cauldron m
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
forall (m :: * -> *).
Cauldron m
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
cauldronRegs
cauldronRegs :: Cauldron m -> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
cauldronRegs :: forall (m :: * -> *).
Cauldron m
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
cauldronRegs Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap} =
(TypeRep
-> SomeRecipe m
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack))
-> Map TypeRep (SomeRecipe m)
-> (Map TypeRep (CallStack, Dynamic), Map TypeRep CallStack)
forall m k a. Monoid m => (k -> a -> m) -> Map k a -> m
Map.foldMapWithKey
do \TypeRep
rep SomeRecipe m
aRecipe -> (SomeRecipe m -> Map TypeRep (CallStack, Dynamic)
forall (m :: * -> *).
SomeRecipe m -> Map TypeRep (CallStack, Dynamic)
recipeRegs SomeRecipe m
aRecipe, TypeRep -> CallStack -> Map TypeRep CallStack
forall k a. k -> a -> Map k a
Map.singleton TypeRep
rep (SomeRecipe m -> CallStack
forall (m :: * -> *). SomeRecipe m -> CallStack
getRecipeCallStack SomeRecipe m
aRecipe))
Map TypeRep (SomeRecipe m)
recipeMap
recipeRegs :: SomeRecipe m -> Map TypeRep (CallStack, Dynamic)
recipeRegs :: forall (m :: * -> *).
SomeRecipe m -> Map TypeRep (CallStack, Dynamic)
recipeRegs (SomeRecipe CallStack
_ (Recipe {Constructor m bean
bean :: forall (m :: * -> *) bean. Recipe m bean -> Constructor m bean
bean :: Constructor m bean
bean, Seq (Constructor m bean)
decos :: forall (m :: * -> *) bean.
Recipe m bean -> Seq (Constructor m bean)
decos :: Seq (Constructor m bean)
decos})) = do
let extractRegReps :: Constructor m bean -> Map TypeRep (CallStack, Dynamic)
extractRegReps Constructor m bean
c = (Constructor m bean -> CallStack
forall (m :: * -> *) bean. Constructor m bean -> CallStack
getConstructorCallStack Constructor m bean
c,) (Dynamic -> (CallStack, Dynamic))
-> Map TypeRep Dynamic -> Map TypeRep (CallStack, Dynamic)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (\ConstructorReps {Map TypeRep Dynamic
regReps :: ConstructorReps -> Map TypeRep Dynamic
regReps :: Map TypeRep Dynamic
regReps} -> Map TypeRep Dynamic
regReps) (Constructor m bean -> ConstructorReps
forall {m :: * -> *} bean.
Typeable bean =>
Constructor m bean -> ConstructorReps
constructorReps Constructor m bean
c)
Constructor m bean -> Map TypeRep (CallStack, Dynamic)
forall {bean} {m :: * -> *}.
Typeable bean =>
Constructor m bean -> Map TypeRep (CallStack, Dynamic)
extractRegReps Constructor m bean
bean
Map TypeRep (CallStack, Dynamic)
-> Map TypeRep (CallStack, Dynamic)
-> Map TypeRep (CallStack, Dynamic)
forall a. Semigroup a => a -> a -> a
<> (Constructor m bean -> Map TypeRep (CallStack, Dynamic))
-> Seq (Constructor m bean) -> Map TypeRep (CallStack, Dynamic)
forall m a. Monoid m => (a -> m) -> Seq a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Constructor m bean -> Map TypeRep (CallStack, Dynamic)
forall {bean} {m :: * -> *}.
Typeable bean =>
Constructor m bean -> Map TypeRep (CallStack, Dynamic)
extractRegReps Seq (Constructor m bean)
decos
data MissingDependencies = MissingDependencies CallStack TypeRep (Set TypeRep)
deriving stock (Int -> MissingDependencies -> ShowS
[MissingDependencies] -> ShowS
MissingDependencies -> String
(Int -> MissingDependencies -> ShowS)
-> (MissingDependencies -> String)
-> ([MissingDependencies] -> ShowS)
-> Show MissingDependencies
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MissingDependencies -> ShowS
showsPrec :: Int -> MissingDependencies -> ShowS
$cshow :: MissingDependencies -> String
show :: MissingDependencies -> String
$cshowList :: [MissingDependencies] -> ShowS
showList :: [MissingDependencies] -> ShowS
Show)
checkMissingDeps ::
Set TypeRep ->
Tree (Cauldron m) ->
Either MissingDependencies ()
checkMissingDeps :: forall (m :: * -> *).
Set TypeRep -> Tree (Cauldron m) -> Either MissingDependencies ()
checkMissingDeps Set TypeRep
accums Tree (Cauldron m)
treecipes = do
let decoratedTreecipes :: Tree (Map TypeRep (SomeRecipe m), Cauldron m)
decoratedTreecipes = (Map TypeRep (SomeRecipe m), Tree (Cauldron m))
-> Tree (Map TypeRep (SomeRecipe m), Cauldron m)
forall (m :: * -> *).
(Map TypeRep (SomeRecipe m), Tree (Cauldron m))
-> Tree (Map TypeRep (SomeRecipe m), Cauldron m)
decorate (Map TypeRep (SomeRecipe m)
forall k a. Map k a
Map.empty, Tree (Cauldron m)
treecipes)
missing :: Tree (Either MissingDependencies ())
missing =
Tree (Map TypeRep (SomeRecipe m), Cauldron m)
decoratedTreecipes Tree (Map TypeRep (SomeRecipe m), Cauldron m)
-> ((Map TypeRep (SomeRecipe m), Cauldron m)
-> Either MissingDependencies ())
-> Tree (Either MissingDependencies ())
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \(Map TypeRep (SomeRecipe m)
available, Cauldron m
requested) ->
do Set TypeRep
-> Set TypeRep -> Cauldron m -> Either MissingDependencies ()
forall (m :: * -> *).
Set TypeRep
-> Set TypeRep -> Cauldron m -> Either MissingDependencies ()
checkMissingDepsCauldron Set TypeRep
accums (Map TypeRep (SomeRecipe m) -> Set TypeRep
forall k a. Map k a -> Set k
Map.keysSet Map TypeRep (SomeRecipe m)
available) Cauldron m
requested
Tree (Either MissingDependencies ())
-> Either MissingDependencies ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ Tree (Either MissingDependencies ())
missing
where
decorate ::
(Map TypeRep (SomeRecipe m), Tree (Cauldron m)) ->
Tree (Map TypeRep (SomeRecipe m), Cauldron m)
decorate :: forall (m :: * -> *).
(Map TypeRep (SomeRecipe m), Tree (Cauldron m))
-> Tree (Map TypeRep (SomeRecipe m), Cauldron m)
decorate = ((Map TypeRep (SomeRecipe m), Tree (Cauldron m))
-> ((Map TypeRep (SomeRecipe m), Cauldron m),
[(Map TypeRep (SomeRecipe m), Tree (Cauldron m))]))
-> (Map TypeRep (SomeRecipe m), Tree (Cauldron m))
-> Tree (Map TypeRep (SomeRecipe m), Cauldron m)
forall b a. (b -> (a, [b])) -> b -> Tree a
unfoldTree
do
\(Map TypeRep (SomeRecipe m)
acc, Node (current :: Cauldron m
current@Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap}) [Tree (Cauldron m)]
rest) ->
let
newAcc :: Map TypeRep (SomeRecipe m)
newAcc = Map TypeRep (SomeRecipe m)
recipeMap Map TypeRep (SomeRecipe m)
-> Map TypeRep (SomeRecipe m) -> Map TypeRep (SomeRecipe m)
forall k a. Ord k => Map k a -> Map k a -> Map k a
`Map.union` Map TypeRep (SomeRecipe m)
acc
newSeeds :: [(Map TypeRep (SomeRecipe m), Tree (Cauldron m))]
newSeeds = do
z <- [Tree (Cauldron m)]
rest
[(newAcc, z)]
in ((Map TypeRep (SomeRecipe m)
newAcc, Cauldron m
current), [(Map TypeRep (SomeRecipe m), Tree (Cauldron m))]
newSeeds)
checkMissingDepsCauldron ::
Set TypeRep ->
Set TypeRep ->
Cauldron m ->
Either MissingDependencies ()
checkMissingDepsCauldron :: forall (m :: * -> *).
Set TypeRep
-> Set TypeRep -> Cauldron m -> Either MissingDependencies ()
checkMissingDepsCauldron Set TypeRep
accums Set TypeRep
available Cauldron m
cauldron =
[(CallStack, TypeRep, Set TypeRep)]
-> ((CallStack, TypeRep, Set TypeRep)
-> Either MissingDependencies ())
-> Either MissingDependencies ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
Data.Foldable.for_ (Cauldron m -> [(CallStack, TypeRep, Set TypeRep)]
forall (m :: * -> *).
Cauldron m -> [(CallStack, TypeRep, Set TypeRep)]
demandsByConstructorsInCauldron Cauldron m
cauldron) \(CallStack
stack, TypeRep
tr, Set TypeRep
demanded) ->
let missing :: Set TypeRep
missing = (TypeRep -> Bool) -> Set TypeRep -> Set TypeRep
forall a. (a -> Bool) -> Set a -> Set a
Set.filter (TypeRep -> Set TypeRep -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.notMember` (Set TypeRep
available Set TypeRep -> Set TypeRep -> Set TypeRep
forall a. Ord a => Set a -> Set a -> Set a
`Set.union` Set TypeRep
accums)) Set TypeRep
demanded
in if Set TypeRep -> Bool
forall a. Set a -> Bool
Set.null Set TypeRep
missing
then () -> Either MissingDependencies ()
forall a b. b -> Either a b
Right ()
else MissingDependencies -> Either MissingDependencies ()
forall a b. a -> Either a b
Left (MissingDependencies -> Either MissingDependencies ())
-> MissingDependencies -> Either MissingDependencies ()
forall a b. (a -> b) -> a -> b
$ CallStack -> TypeRep -> Set TypeRep -> MissingDependencies
MissingDependencies CallStack
stack TypeRep
tr Set TypeRep
missing
demandsByConstructorsInCauldron :: Cauldron m -> [(CallStack, TypeRep, Set TypeRep)]
demandsByConstructorsInCauldron :: forall (m :: * -> *).
Cauldron m -> [(CallStack, TypeRep, Set TypeRep)]
demandsByConstructorsInCauldron Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap} = do
(tr, SomeRecipe _ (Recipe {bean, decos})) <- Map TypeRep (SomeRecipe m) -> [(TypeRep, SomeRecipe m)]
forall k a. Map k a -> [(k, a)]
Map.toList Map TypeRep (SomeRecipe m)
recipeMap
( let ConstructorReps {argReps = beanArgReps} = constructorReps bean
in [(getConstructorCallStack bean, tr, beanArgReps)]
)
++ do
decoCon <- Data.Foldable.toList decos
let ConstructorReps {argReps = decoArgReps} = constructorReps decoCon
in [(getConstructorCallStack decoCon, tr, decoArgReps)]
newtype DependencyCycle = DependencyCycle (NonEmpty (BeanConstructionStep, Maybe CallStack))
deriving stock (Int -> DependencyCycle -> ShowS
[DependencyCycle] -> ShowS
DependencyCycle -> String
(Int -> DependencyCycle -> ShowS)
-> (DependencyCycle -> String)
-> ([DependencyCycle] -> ShowS)
-> Show DependencyCycle
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DependencyCycle -> ShowS
showsPrec :: Int -> DependencyCycle -> ShowS
$cshow :: DependencyCycle -> String
show :: DependencyCycle -> String
$cshowList :: [DependencyCycle] -> ShowS
showList :: [DependencyCycle] -> ShowS
Show)
buildPlans :: Set TypeRep -> Tree (Fire m, Cauldron m) -> Either DependencyCycle (Tree (Plan, Fire m, Cauldron m))
buildPlans :: forall (m :: * -> *).
Set TypeRep
-> Tree (Fire m, Cauldron m)
-> Either DependencyCycle (Tree (Plan, Fire m, Cauldron m))
buildPlans Set TypeRep
secondary = ((Fire m, Cauldron m)
-> Either DependencyCycle (Plan, Fire m, Cauldron m))
-> Tree (Fire m, Cauldron m)
-> Either DependencyCycle (Tree (Plan, Fire m, Cauldron m))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Tree a -> f (Tree b)
traverse \(fire :: Fire m
fire@Fire {(BeanConstructionStep, BeanConstructionStep) -> Bool
shouldOmitDependency :: forall (m :: * -> *).
Fire m -> (BeanConstructionStep, BeanConstructionStep) -> Bool
shouldOmitDependency :: (BeanConstructionStep, BeanConstructionStep) -> Bool
shouldOmitDependency}, Cauldron m
cauldron) -> do
let (Map BeanConstructionStep CallStack
locations, [(BeanConstructionStep, BeanConstructionStep)]
deps) = Set TypeRep
-> Cauldron m
-> (Map BeanConstructionStep CallStack,
[(BeanConstructionStep, BeanConstructionStep)])
forall (m :: * -> *).
Set TypeRep
-> Cauldron m
-> (Map BeanConstructionStep CallStack,
[(BeanConstructionStep, BeanConstructionStep)])
buildDepsCauldron Set TypeRep
secondary Cauldron m
cauldron
let graph :: AdjacencyMap BeanConstructionStep
graph = [(BeanConstructionStep, BeanConstructionStep)]
-> AdjacencyMap BeanConstructionStep
forall a. Ord a => [(a, a)] -> AdjacencyMap a
Graph.edges ([(BeanConstructionStep, BeanConstructionStep)]
-> AdjacencyMap BeanConstructionStep)
-> [(BeanConstructionStep, BeanConstructionStep)]
-> AdjacencyMap BeanConstructionStep
forall a b. (a -> b) -> a -> b
$ ((BeanConstructionStep, BeanConstructionStep) -> Bool)
-> [(BeanConstructionStep, BeanConstructionStep)]
-> [(BeanConstructionStep, BeanConstructionStep)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> ((BeanConstructionStep, BeanConstructionStep) -> Bool)
-> (BeanConstructionStep, BeanConstructionStep)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (BeanConstructionStep, BeanConstructionStep) -> Bool
shouldOmitDependency) [(BeanConstructionStep, BeanConstructionStep)]
deps
case AdjacencyMap BeanConstructionStep
-> Either (Cycle BeanConstructionStep) Plan
forall a. Ord a => AdjacencyMap a -> Either (Cycle a) [a]
Graph.topSort AdjacencyMap BeanConstructionStep
graph of
Left Cycle BeanConstructionStep
recipeCycle ->
DependencyCycle
-> Either DependencyCycle (Plan, Fire m, Cauldron m)
forall a b. a -> Either a b
Left (DependencyCycle
-> Either DependencyCycle (Plan, Fire m, Cauldron m))
-> DependencyCycle
-> Either DependencyCycle (Plan, Fire m, Cauldron m)
forall a b. (a -> b) -> a -> b
$ NonEmpty (BeanConstructionStep, Maybe CallStack) -> DependencyCycle
DependencyCycle (NonEmpty (BeanConstructionStep, Maybe CallStack)
-> DependencyCycle)
-> NonEmpty (BeanConstructionStep, Maybe CallStack)
-> DependencyCycle
forall a b. (a -> b) -> a -> b
$ Cycle BeanConstructionStep
recipeCycle Cycle BeanConstructionStep
-> (BeanConstructionStep
-> (BeanConstructionStep, Maybe CallStack))
-> NonEmpty (BeanConstructionStep, Maybe CallStack)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \BeanConstructionStep
step -> (BeanConstructionStep
step, BeanConstructionStep
-> Map BeanConstructionStep CallStack -> Maybe CallStack
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup BeanConstructionStep
step Map BeanConstructionStep CallStack
locations)
Right (Plan -> Plan
forall a. [a] -> [a]
reverse -> Plan
plan) -> do
(Plan, Fire m, Cauldron m)
-> Either DependencyCycle (Plan, Fire m, Cauldron m)
forall a b. b -> Either a b
Right (Plan
plan, Fire m
fire, Cauldron m
cauldron)
buildDepsCauldron :: Set TypeRep -> Cauldron m -> (Map BeanConstructionStep CallStack, [(BeanConstructionStep, BeanConstructionStep)])
buildDepsCauldron :: forall (m :: * -> *).
Set TypeRep
-> Cauldron m
-> (Map BeanConstructionStep CallStack,
[(BeanConstructionStep, BeanConstructionStep)])
buildDepsCauldron Set TypeRep
secondary Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap} = do
let makeTargetStep :: TypeRep -> BeanConstructionStep
makeTargetStep :: TypeRep -> BeanConstructionStep
makeTargetStep TypeRep
rep =
if TypeRep
rep TypeRep -> Set TypeRep -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` Set TypeRep
secondary
then TypeRep -> BeanConstructionStep
SecondaryBean TypeRep
rep
else TypeRep -> BeanConstructionStep
PrimaryBean TypeRep
rep
Map TypeRep (SomeRecipe m)
recipeMap
Map TypeRep (SomeRecipe m)
-> (Map TypeRep (SomeRecipe m)
-> (Map BeanConstructionStep CallStack,
[(BeanConstructionStep, BeanConstructionStep)]))
-> (Map BeanConstructionStep CallStack,
[(BeanConstructionStep, BeanConstructionStep)])
forall a b. a -> (a -> b) -> b
& (TypeRep
-> SomeRecipe m
-> (Map BeanConstructionStep CallStack,
[(BeanConstructionStep, BeanConstructionStep)]))
-> Map TypeRep (SomeRecipe m)
-> (Map BeanConstructionStep CallStack,
[(BeanConstructionStep, BeanConstructionStep)])
forall m k a. Monoid m => (k -> a -> m) -> Map k a -> m
Map.foldMapWithKey
\TypeRep
beanRep
SomeRecipe
{ CallStack
_recipeCallStack :: forall (m :: * -> *). SomeRecipe m -> CallStack
_recipeCallStack :: CallStack
_recipeCallStack,
_recipe :: ()
_recipe =
Recipe
{ bean :: forall (m :: * -> *) bean. Recipe m bean -> Constructor m bean
bean = Constructor m bean
bean :: Constructor m bean,
Seq (Constructor m bean)
decos :: forall (m :: * -> *) bean.
Recipe m bean -> Seq (Constructor m bean)
decos :: Seq (Constructor m bean)
decos
}
} ->
do
let bareBean :: BeanConstructionStep
bareBean = TypeRep -> BeanConstructionStep
BarePrimaryBean TypeRep
beanRep
boiledBean :: BeanConstructionStep
boiledBean = TypeRep -> BeanConstructionStep
PrimaryBean TypeRep
beanRep
decoSteps :: [(BeanConstructionStep, Constructor m bean)]
decoSteps = do
(decoIndex, decoCon) <- [Int] -> [Constructor m bean] -> [(Int, Constructor m bean)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 :: Int ..] (Seq (Constructor m bean) -> [Constructor m bean]
forall a. Seq a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Data.Foldable.toList Seq (Constructor m bean)
decos)
[(PrimaryBeanDeco beanRep decoIndex, decoCon)]
beanDeps :: [(BeanConstructionStep, BeanConstructionStep)]
beanDeps = do
(TypeRep -> BeanConstructionStep)
-> BeanConstructionStep
-> ConstructorReps
-> [(BeanConstructionStep, BeanConstructionStep)]
constructorEdges TypeRep -> BeanConstructionStep
makeTargetStep BeanConstructionStep
bareBean (Constructor m bean -> ConstructorReps
forall {m :: * -> *} bean.
Typeable bean =>
Constructor m bean -> ConstructorReps
constructorReps Constructor m bean
bean)
decoDeps :: [(BeanConstructionStep, BeanConstructionStep)]
decoDeps = do
(decoStep, decoCon) <- [(BeanConstructionStep, Constructor m bean)]
decoSteps
constructorEdges makeTargetStep decoStep (removeBeanFromArgs do constructorReps decoCon)
innerSteps :: Cycle BeanConstructionStep
innerSteps = BeanConstructionStep
bareBean BeanConstructionStep -> Plan -> Cycle BeanConstructionStep
forall a. a -> [a] -> NonEmpty a
Data.List.NonEmpty.:| ((BeanConstructionStep, Constructor m bean) -> BeanConstructionStep
forall a b. (a, b) -> a
fst ((BeanConstructionStep, Constructor m bean)
-> BeanConstructionStep)
-> [(BeanConstructionStep, Constructor m bean)] -> Plan
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(BeanConstructionStep, Constructor m bean)]
decoSteps) Plan -> Plan -> Plan
forall a. [a] -> [a] -> [a]
++ [BeanConstructionStep
boiledBean]
innerDeps :: [(BeanConstructionStep, BeanConstructionStep)]
innerDeps =
(TypeRep -> BeanConstructionStep
PrimaryBean TypeRep
beanRep, TypeRep -> BeanConstructionStep
BarePrimaryBean TypeRep
beanRep)
(BeanConstructionStep, BeanConstructionStep)
-> [(BeanConstructionStep, BeanConstructionStep)]
-> [(BeanConstructionStep, BeanConstructionStep)]
forall a. a -> [a] -> [a]
:
Plan -> Plan -> [(BeanConstructionStep, BeanConstructionStep)]
forall a b. [a] -> [b] -> [(a, b)]
zip (Cycle BeanConstructionStep -> Plan
forall a. NonEmpty a -> [a]
Data.List.NonEmpty.tail Cycle BeanConstructionStep
innerSteps) (Cycle BeanConstructionStep -> Plan
forall a. NonEmpty a -> [a]
Data.List.NonEmpty.toList Cycle BeanConstructionStep
innerSteps)
( [(BeanConstructionStep, CallStack)]
-> Map BeanConstructionStep CallStack
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(BeanConstructionStep, CallStack)]
-> Map BeanConstructionStep CallStack)
-> [(BeanConstructionStep, CallStack)]
-> Map BeanConstructionStep CallStack
forall a b. (a -> b) -> a -> b
$
[ (BeanConstructionStep
bareBean, Constructor m bean -> CallStack
forall (m :: * -> *) bean. Constructor m bean -> CallStack
getConstructorCallStack Constructor m bean
bean),
(BeanConstructionStep
boiledBean, CallStack
_recipeCallStack)
]
[(BeanConstructionStep, CallStack)]
-> [(BeanConstructionStep, CallStack)]
-> [(BeanConstructionStep, CallStack)]
forall a. [a] -> [a] -> [a]
++ do
(decoStep, decoCon) <- [(BeanConstructionStep, Constructor m bean)]
decoSteps
[(decoStep, getConstructorCallStack decoCon)],
[(BeanConstructionStep, BeanConstructionStep)]
beanDeps [(BeanConstructionStep, BeanConstructionStep)]
-> [(BeanConstructionStep, BeanConstructionStep)]
-> [(BeanConstructionStep, BeanConstructionStep)]
forall a. [a] -> [a] -> [a]
++ [(BeanConstructionStep, BeanConstructionStep)]
decoDeps [(BeanConstructionStep, BeanConstructionStep)]
-> [(BeanConstructionStep, BeanConstructionStep)]
-> [(BeanConstructionStep, BeanConstructionStep)]
forall a. [a] -> [a] -> [a]
++ [(BeanConstructionStep, BeanConstructionStep)]
innerDeps
)
constructorEdges ::
(TypeRep -> BeanConstructionStep) ->
BeanConstructionStep ->
ConstructorReps ->
[(BeanConstructionStep, BeanConstructionStep)]
constructorEdges :: (TypeRep -> BeanConstructionStep)
-> BeanConstructionStep
-> ConstructorReps
-> [(BeanConstructionStep, BeanConstructionStep)]
constructorEdges TypeRep -> BeanConstructionStep
makeTargetStep BeanConstructionStep
item (ConstructorReps {Set TypeRep
argReps :: ConstructorReps -> Set TypeRep
argReps :: Set TypeRep
argReps, Map TypeRep Dynamic
regReps :: ConstructorReps -> Map TypeRep Dynamic
regReps :: Map TypeRep Dynamic
regReps}) =
( do
argRep <- Set TypeRep -> [TypeRep]
forall a. Set a -> [a]
Set.toList Set TypeRep
argReps
let argStep = TypeRep -> BeanConstructionStep
makeTargetStep TypeRep
argRep
[(item, argStep)]
)
[(BeanConstructionStep, BeanConstructionStep)]
-> [(BeanConstructionStep, BeanConstructionStep)]
-> [(BeanConstructionStep, BeanConstructionStep)]
forall a. [a] -> [a] -> [a]
++
( do
(regRep, _) <- Map TypeRep Dynamic -> [(TypeRep, Dynamic)]
forall k a. Map k a -> [(k, a)]
Map.toList Map TypeRep Dynamic
regReps
let repStep = TypeRep -> BeanConstructionStep
SecondaryBean TypeRep
regRep
[(repStep, item)]
)
followPlan ::
(Monad m) =>
Beans ->
(Tree (Plan, Fire m, Cauldron m)) ->
m (Tree Beans)
followPlan :: forall (m :: * -> *).
Monad m =>
Beans -> Tree (Plan, Fire m, Cauldron m) -> m (Tree Beans)
followPlan Beans
initialBeans Tree (Plan, Fire m, Cauldron m)
treecipes =
let secondaryBeanReps :: Set TypeRep
secondaryBeanReps = Beans -> Set TypeRep
Cauldron.Beans.keysSet Beans
initialBeans
in ((Beans, Tree (Plan, Fire m, Cauldron m))
-> m (Beans, [(Beans, Tree (Plan, Fire m, Cauldron m))]))
-> (Beans, Tree (Plan, Fire m, Cauldron m)) -> m (Tree Beans)
forall (m :: * -> *) b a.
Monad m =>
(b -> m (a, [b])) -> b -> m (Tree a)
unfoldTreeM
( \(Beans
previousStageBeans, Node (Plan
plan, Fire {Cauldron m -> Set TypeRep -> Beans -> Plan -> m Beans
followPlanCauldron :: forall (m :: * -> *).
Fire m -> Cauldron m -> Set TypeRep -> Beans -> Plan -> m Beans
followPlanCauldron :: Cauldron m -> Set TypeRep -> Beans -> Plan -> m Beans
followPlanCauldron}, Cauldron m
cauldron) [Tree (Plan, Fire m, Cauldron m)]
rest) -> do
currentStageBeans <- Cauldron m -> Set TypeRep -> Beans -> Plan -> m Beans
followPlanCauldron Cauldron m
cauldron Set TypeRep
secondaryBeanReps Beans
previousStageBeans Plan
plan
pure (currentStageBeans, (,) currentStageBeans <$> rest)
)
(Beans
initialBeans, Tree (Plan, Fire m, Cauldron m)
treecipes)
followPlanStep ::
(Monad m) =>
(TypeRep -> Beans -> Beans) ->
(TypeRep -> Beans -> Beans) ->
Cauldron m ->
Beans ->
Beans ->
BeanConstructionStep ->
m Beans
followPlanStep :: forall (m :: * -> *).
Monad m =>
(TypeRep -> Beans -> Beans)
-> (TypeRep -> Beans -> Beans)
-> Cauldron m
-> Beans
-> Beans
-> BeanConstructionStep
-> m Beans
followPlanStep TypeRep -> Beans -> Beans
makeBareView TypeRep -> Beans -> Beans
makeDecoView Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap} Beans
final Beans
super BeanConstructionStep
item =
case BeanConstructionStep
item of
BarePrimaryBean TypeRep
rep -> case Maybe (SomeRecipe m) -> SomeRecipe m
forall a. HasCallStack => Maybe a -> a
fromJust do TypeRep -> Map TypeRep (SomeRecipe m) -> Maybe (SomeRecipe m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup TypeRep
rep Map TypeRep (SomeRecipe m)
recipeMap of
SomeRecipe {_recipe :: ()
_recipe = Recipe {Constructor m bean
bean :: forall (m :: * -> *) bean. Recipe m bean -> Constructor m bean
bean :: Constructor m bean
bean}} -> do
let ConstructorReps {TypeRep
beanRep :: ConstructorReps -> TypeRep
beanRep :: TypeRep
beanRep} = Constructor m bean -> ConstructorReps
forall {m :: * -> *} bean.
Typeable bean =>
Constructor m bean -> ConstructorReps
constructorReps Constructor m bean
bean
inserter <- Constructor m bean -> Beans -> Beans -> m (Beans -> Beans)
forall (m :: * -> *) bean.
(Monad m, Typeable bean) =>
Constructor m bean -> Beans -> Beans -> m (Beans -> Beans)
followConstructor Constructor m bean
bean Beans
final (TypeRep -> Beans -> Beans
makeBareView TypeRep
beanRep Beans
super)
pure do inserter super
PrimaryBeanDeco TypeRep
rep Int
index -> case Maybe (SomeRecipe m) -> SomeRecipe m
forall a. HasCallStack => Maybe a -> a
fromJust do TypeRep -> Map TypeRep (SomeRecipe m) -> Maybe (SomeRecipe m)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup TypeRep
rep Map TypeRep (SomeRecipe m)
recipeMap of
SomeRecipe {_recipe :: ()
_recipe = Recipe {Seq (Constructor m bean)
decos :: forall (m :: * -> *) bean.
Recipe m bean -> Seq (Constructor m bean)
decos :: Seq (Constructor m bean)
decos}} -> do
let deco :: Constructor m bean
deco = Seq (Constructor m bean)
decos Seq (Constructor m bean) -> Int -> Constructor m bean
forall a. Seq a -> Int -> a
`Data.Sequence.index` Int
index
let ConstructorReps {TypeRep
beanRep :: ConstructorReps -> TypeRep
beanRep :: TypeRep
beanRep} = Constructor m bean -> ConstructorReps
forall {m :: * -> *} bean.
Typeable bean =>
Constructor m bean -> ConstructorReps
constructorReps Constructor m bean
deco
inserter <- Constructor m bean -> Beans -> Beans -> m (Beans -> Beans)
forall (m :: * -> *) bean.
(Monad m, Typeable bean) =>
Constructor m bean -> Beans -> Beans -> m (Beans -> Beans)
followConstructor Constructor m bean
deco Beans
final (TypeRep -> Beans -> Beans
makeDecoView TypeRep
beanRep Beans
super)
pure do inserter super
PrimaryBean {} -> Beans -> m Beans
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Beans
super
SecondaryBean {} -> Beans -> m Beans
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Beans
super
followConstructor ::
(Monad m, Typeable bean) =>
Constructor m bean ->
Beans ->
Beans ->
m (Beans -> Beans)
followConstructor :: forall (m :: * -> *) bean.
(Monad m, Typeable bean) =>
Constructor m bean -> Beans -> Beans -> m (Beans -> Beans)
followConstructor Constructor m bean
c Beans
final Beans
super = do
(regs, bean) <- [Beans] -> Constructor m bean -> m (Beans, bean)
forall (m :: * -> *) bean.
Monad m =>
[Beans] -> Constructor m bean -> m (Beans, bean)
runConstructor [Beans
super, Beans
final] Constructor m bean
c
pure \Beans
bs ->
Set SomeMonoidTypeRep -> Beans -> Beans -> Beans
Cauldron.Beans.unionBeansMonoidally (Args (m (Regs bean)) -> Set SomeMonoidTypeRep
forall a. Args a -> Set SomeMonoidTypeRep
getRegsReps (Constructor m bean -> Args (m (Regs bean))
forall (m :: * -> *) bean.
Constructor m bean -> Args (m (Regs bean))
getConstructorArgs Constructor m bean
c)) Beans
bs Beans
regs
Beans -> (Beans -> Beans) -> Beans
forall a b. a -> (a -> b) -> b
& bean -> Beans -> Beans
forall bean. Typeable bean => bean -> Beans -> Beans
Cauldron.Beans.insert bean
bean
data RecipeError
=
MissingDependenciesError MissingDependencies
|
DoubleDutyBeansError DoubleDutyBeans
|
DependencyCycleError DependencyCycle
deriving stock (Int -> RecipeError -> ShowS
[RecipeError] -> ShowS
RecipeError -> String
(Int -> RecipeError -> ShowS)
-> (RecipeError -> String)
-> ([RecipeError] -> ShowS)
-> Show RecipeError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> RecipeError -> ShowS
showsPrec :: Int -> RecipeError -> ShowS
$cshow :: RecipeError -> String
show :: RecipeError -> String
$cshowList :: [RecipeError] -> ShowS
showList :: [RecipeError] -> ShowS
Show)
instance Exception RecipeError where
displayException :: RecipeError -> String
displayException = RecipeError -> String
prettyRecipeError
prettyRecipeError :: RecipeError -> String
prettyRecipeError :: RecipeError -> String
prettyRecipeError = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
Data.List.intercalate String
"\n" ([String] -> String)
-> (RecipeError -> [String]) -> RecipeError -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RecipeError -> [String]
prettyRecipeErrorLines
prettyRecipeErrorLines :: RecipeError -> [String]
prettyRecipeErrorLines :: RecipeError -> [String]
prettyRecipeErrorLines = \case
MissingDependenciesError
(MissingDependencies CallStack
constructorCallStack TypeRep
constructorResultRep Set TypeRep
missingDependenciesReps) ->
[ String
"This constructor for a value of type "
String -> ShowS
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show TypeRep
constructorResultRep
String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
":"
]
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ((String
"\t" String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> [String] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CallStack -> [String]
prettyCallStackLines CallStack
constructorCallStack)
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [ String
"is missing the following dependencies:"
]
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ do
rep <- Set TypeRep -> [TypeRep]
forall a. Set a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Data.Foldable.toList Set TypeRep
missingDependenciesReps
["- " ++ show rep]
DoubleDutyBeansError (DoubleDutyBeans Map TypeRep (CallStack, CallStack)
doubleDutyMap) ->
[ String
"The following beans work both as primary beans and secondary beans:"
]
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ( ((TypeRep -> (CallStack, CallStack) -> [String])
-> Map TypeRep (CallStack, CallStack) -> [String])
-> Map TypeRep (CallStack, CallStack)
-> (TypeRep -> (CallStack, CallStack) -> [String])
-> [String]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (TypeRep -> (CallStack, CallStack) -> [String])
-> Map TypeRep (CallStack, CallStack) -> [String]
forall m k a. Monoid m => (k -> a -> m) -> Map k a -> m
Map.foldMapWithKey Map TypeRep (CallStack, CallStack)
doubleDutyMap \TypeRep
rep (CallStack
secCS, CallStack
primCS) ->
[ String
"- " String -> ShowS
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show TypeRep
rep String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" is a secondary bean in this constructor:"
]
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ((String
"\t" String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> [String] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CallStack -> [String]
prettyCallStackLines CallStack
secCS)
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [ String
" and a primary bean in this recipe:"
]
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ((String
"\t" String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> [String] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CallStack -> [String]
prettyCallStackLines CallStack
primCS)
)
DependencyCycleError (DependencyCycle NonEmpty (BeanConstructionStep, Maybe CallStack)
theCycle) ->
[ String
"Forbidden dependency cycle between bean construction steps:"
]
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ ( (((BeanConstructionStep, Maybe CallStack) -> [String])
-> NonEmpty (BeanConstructionStep, Maybe CallStack) -> [String])
-> NonEmpty (BeanConstructionStep, Maybe CallStack)
-> ((BeanConstructionStep, Maybe CallStack) -> [String])
-> [String]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((BeanConstructionStep, Maybe CallStack) -> [String])
-> NonEmpty (BeanConstructionStep, Maybe CallStack) -> [String]
forall m a. Monoid m => (a -> m) -> NonEmpty a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap NonEmpty (BeanConstructionStep, Maybe CallStack)
theCycle \(BeanConstructionStep
step, Maybe CallStack
mstack) ->
[ String
"- " String -> ShowS
forall a. [a] -> [a] -> [a]
++ case BeanConstructionStep
step of
BarePrimaryBean TypeRep
rep -> String
"Bare bean " String -> ShowS
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show TypeRep
rep
PrimaryBeanDeco TypeRep
rep Int
i -> String
"Decorator " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" for bean " String -> ShowS
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show TypeRep
rep
PrimaryBean TypeRep
rep -> String
"Complete bean " String -> ShowS
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show TypeRep
rep
SecondaryBean TypeRep
rep -> String
"Secondary bean " String -> ShowS
forall a. [a] -> [a] -> [a]
++ TypeRep -> String
forall a. Show a => a -> String
show TypeRep
rep
]
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ case Maybe CallStack
mstack of
Maybe CallStack
Nothing -> []
Just CallStack
stack -> ((String
"\t" String -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> [String] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CallStack -> [String]
prettyCallStackLines CallStack
stack)
)
newtype DependencyGraph = DependencyGraph {DependencyGraph -> AdjacencyMap BeanConstructionStep
graph :: AdjacencyMap BeanConstructionStep}
deriving newtype (Int -> DependencyGraph -> ShowS
[DependencyGraph] -> ShowS
DependencyGraph -> String
(Int -> DependencyGraph -> ShowS)
-> (DependencyGraph -> String)
-> ([DependencyGraph] -> ShowS)
-> Show DependencyGraph
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DependencyGraph -> ShowS
showsPrec :: Int -> DependencyGraph -> ShowS
$cshow :: DependencyGraph -> String
show :: DependencyGraph -> String
$cshowList :: [DependencyGraph] -> ShowS
showList :: [DependencyGraph] -> ShowS
Show, DependencyGraph -> DependencyGraph -> Bool
(DependencyGraph -> DependencyGraph -> Bool)
-> (DependencyGraph -> DependencyGraph -> Bool)
-> Eq DependencyGraph
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DependencyGraph -> DependencyGraph -> Bool
== :: DependencyGraph -> DependencyGraph -> Bool
$c/= :: DependencyGraph -> DependencyGraph -> Bool
/= :: DependencyGraph -> DependencyGraph -> Bool
Eq, Eq DependencyGraph
Eq DependencyGraph =>
(DependencyGraph -> DependencyGraph -> Ordering)
-> (DependencyGraph -> DependencyGraph -> Bool)
-> (DependencyGraph -> DependencyGraph -> Bool)
-> (DependencyGraph -> DependencyGraph -> Bool)
-> (DependencyGraph -> DependencyGraph -> Bool)
-> (DependencyGraph -> DependencyGraph -> DependencyGraph)
-> (DependencyGraph -> DependencyGraph -> DependencyGraph)
-> Ord DependencyGraph
DependencyGraph -> DependencyGraph -> Bool
DependencyGraph -> DependencyGraph -> Ordering
DependencyGraph -> DependencyGraph -> DependencyGraph
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
$ccompare :: DependencyGraph -> DependencyGraph -> Ordering
compare :: DependencyGraph -> DependencyGraph -> Ordering
$c< :: DependencyGraph -> DependencyGraph -> Bool
< :: DependencyGraph -> DependencyGraph -> Bool
$c<= :: DependencyGraph -> DependencyGraph -> Bool
<= :: DependencyGraph -> DependencyGraph -> Bool
$c> :: DependencyGraph -> DependencyGraph -> Bool
> :: DependencyGraph -> DependencyGraph -> Bool
$c>= :: DependencyGraph -> DependencyGraph -> Bool
>= :: DependencyGraph -> DependencyGraph -> Bool
$cmax :: DependencyGraph -> DependencyGraph -> DependencyGraph
max :: DependencyGraph -> DependencyGraph -> DependencyGraph
$cmin :: DependencyGraph -> DependencyGraph -> DependencyGraph
min :: DependencyGraph -> DependencyGraph -> DependencyGraph
Ord, NonEmpty DependencyGraph -> DependencyGraph
DependencyGraph -> DependencyGraph -> DependencyGraph
(DependencyGraph -> DependencyGraph -> DependencyGraph)
-> (NonEmpty DependencyGraph -> DependencyGraph)
-> (forall b.
Integral b =>
b -> DependencyGraph -> DependencyGraph)
-> Semigroup DependencyGraph
forall b. Integral b => b -> DependencyGraph -> DependencyGraph
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: DependencyGraph -> DependencyGraph -> DependencyGraph
<> :: DependencyGraph -> DependencyGraph -> DependencyGraph
$csconcat :: NonEmpty DependencyGraph -> DependencyGraph
sconcat :: NonEmpty DependencyGraph -> DependencyGraph
$cstimes :: forall b. Integral b => b -> DependencyGraph -> DependencyGraph
stimes :: forall b. Integral b => b -> DependencyGraph -> DependencyGraph
Semigroup, Semigroup DependencyGraph
DependencyGraph
Semigroup DependencyGraph =>
DependencyGraph
-> (DependencyGraph -> DependencyGraph -> DependencyGraph)
-> ([DependencyGraph] -> DependencyGraph)
-> Monoid DependencyGraph
[DependencyGraph] -> DependencyGraph
DependencyGraph -> DependencyGraph -> DependencyGraph
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: DependencyGraph
mempty :: DependencyGraph
$cmappend :: DependencyGraph -> DependencyGraph -> DependencyGraph
mappend :: DependencyGraph -> DependencyGraph -> DependencyGraph
$cmconcat :: [DependencyGraph] -> DependencyGraph
mconcat :: [DependencyGraph] -> DependencyGraph
Monoid)
toAdjacencyMap :: DependencyGraph -> AdjacencyMap BeanConstructionStep
toAdjacencyMap :: DependencyGraph -> AdjacencyMap BeanConstructionStep
toAdjacencyMap DependencyGraph {AdjacencyMap BeanConstructionStep
graph :: DependencyGraph -> AdjacencyMap BeanConstructionStep
graph :: AdjacencyMap BeanConstructionStep
graph} = AdjacencyMap BeanConstructionStep
graph
removeSecondaryBeans :: DependencyGraph -> DependencyGraph
removeSecondaryBeans :: DependencyGraph -> DependencyGraph
removeSecondaryBeans DependencyGraph {AdjacencyMap BeanConstructionStep
graph :: DependencyGraph -> AdjacencyMap BeanConstructionStep
graph :: AdjacencyMap BeanConstructionStep
graph} =
DependencyGraph {graph :: AdjacencyMap BeanConstructionStep
graph = (BeanConstructionStep -> Bool)
-> AdjacencyMap BeanConstructionStep
-> AdjacencyMap BeanConstructionStep
forall a. (a -> Bool) -> AdjacencyMap a -> AdjacencyMap a
Graph.induce (\case SecondaryBean {} -> Bool
False; BeanConstructionStep
_ -> Bool
True) AdjacencyMap BeanConstructionStep
graph}
removeDecos :: DependencyGraph -> DependencyGraph
removeDecos :: DependencyGraph -> DependencyGraph
removeDecos DependencyGraph {AdjacencyMap BeanConstructionStep
graph :: DependencyGraph -> AdjacencyMap BeanConstructionStep
graph :: AdjacencyMap BeanConstructionStep
graph} =
DependencyGraph {graph :: AdjacencyMap BeanConstructionStep
graph = (BeanConstructionStep -> Bool)
-> AdjacencyMap BeanConstructionStep
-> AdjacencyMap BeanConstructionStep
forall a. (a -> Bool) -> AdjacencyMap a -> AdjacencyMap a
Graph.induce (\case PrimaryBeanDeco {} -> Bool
False; BeanConstructionStep
_ -> Bool
True) AdjacencyMap BeanConstructionStep
graph}
collapseToPrimaryBeans :: DependencyGraph -> DependencyGraph
collapseToPrimaryBeans :: DependencyGraph -> DependencyGraph
collapseToPrimaryBeans DependencyGraph {AdjacencyMap BeanConstructionStep
graph :: DependencyGraph -> AdjacencyMap BeanConstructionStep
graph :: AdjacencyMap BeanConstructionStep
graph} = do
let simplified :: AdjacencyMap BeanConstructionStep
simplified =
(BeanConstructionStep -> BeanConstructionStep)
-> AdjacencyMap BeanConstructionStep
-> AdjacencyMap BeanConstructionStep
forall a b.
(Ord a, Ord b) =>
(a -> b) -> AdjacencyMap a -> AdjacencyMap b
Graph.gmap
( \case
BarePrimaryBean TypeRep
rep -> TypeRep -> BeanConstructionStep
PrimaryBean TypeRep
rep
PrimaryBeanDeco TypeRep
rep Int
_ -> TypeRep -> BeanConstructionStep
PrimaryBean TypeRep
rep
BeanConstructionStep
other -> BeanConstructionStep
other
)
AdjacencyMap BeanConstructionStep
graph
vertices :: Plan
vertices = AdjacencyMap BeanConstructionStep -> Plan
forall a. AdjacencyMap a -> [a]
Graph.vertexList AdjacencyMap BeanConstructionStep
simplified
edges :: [(BeanConstructionStep, BeanConstructionStep)]
edges = AdjacencyMap BeanConstructionStep
-> [(BeanConstructionStep, BeanConstructionStep)]
forall a. AdjacencyMap a -> [(a, a)]
Graph.edgeList AdjacencyMap BeanConstructionStep
simplified
edgesWithoutSelfLoops :: [(BeanConstructionStep, BeanConstructionStep)]
edgesWithoutSelfLoops =
((BeanConstructionStep, BeanConstructionStep) -> Bool)
-> [(BeanConstructionStep, BeanConstructionStep)]
-> [(BeanConstructionStep, BeanConstructionStep)]
forall a. (a -> Bool) -> [a] -> [a]
filter
( \case
(PrimaryBean TypeRep
source, PrimaryBean TypeRep
target) -> if TypeRep
source TypeRep -> TypeRep -> Bool
forall a. Eq a => a -> a -> Bool
== TypeRep
target then Bool
False else Bool
True
(BeanConstructionStep, BeanConstructionStep)
_ -> Bool
True
)
[(BeanConstructionStep, BeanConstructionStep)]
edges
DependencyGraph {graph :: AdjacencyMap BeanConstructionStep
graph = Plan -> AdjacencyMap BeanConstructionStep
forall a. Ord a => [a] -> AdjacencyMap a
Graph.vertices Plan
vertices AdjacencyMap BeanConstructionStep
-> AdjacencyMap BeanConstructionStep
-> AdjacencyMap BeanConstructionStep
forall a.
Ord a =>
AdjacencyMap a -> AdjacencyMap a -> AdjacencyMap a
`Graph.overlay` [(BeanConstructionStep, BeanConstructionStep)]
-> AdjacencyMap BeanConstructionStep
forall a. Ord a => [(a, a)] -> AdjacencyMap a
Graph.edges [(BeanConstructionStep, BeanConstructionStep)]
edgesWithoutSelfLoops}
writeAsDot :: Dot.Style BeanConstructionStep Data.Text.Text -> FilePath -> DependencyGraph -> IO ()
writeAsDot :: Style BeanConstructionStep Text
-> String -> DependencyGraph -> IO ()
writeAsDot Style BeanConstructionStep Text
style String
filepath DependencyGraph {AdjacencyMap BeanConstructionStep
graph :: DependencyGraph -> AdjacencyMap BeanConstructionStep
graph :: AdjacencyMap BeanConstructionStep
graph} = do
let dot :: Text
dot = Style BeanConstructionStep Text
-> AdjacencyMap BeanConstructionStep -> Text
forall s a g.
(IsString s, Monoid s, Ord a, ToGraph g, ToVertex g ~ a) =>
Style a s -> g -> s
Dot.export Style BeanConstructionStep Text
style AdjacencyMap BeanConstructionStep
graph
String -> ByteString -> IO ()
Data.ByteString.writeFile String
filepath (Text -> ByteString
Data.Text.Encoding.encodeUtf8 Text
dot)
defaultStyle :: Maybe RecipeError -> Dot.Style BeanConstructionStep Data.Text.Text
defaultStyle :: Maybe RecipeError -> Style BeanConstructionStep Text
defaultStyle Maybe RecipeError
merr =
((BeanConstructionStep -> Text) -> Style BeanConstructionStep Text
forall s a. Monoid s => (a -> s) -> Style a s
Dot.defaultStyle BeanConstructionStep -> Text
defaultStepToText)
{ Dot.vertexAttributes = \BeanConstructionStep
step -> case Maybe RecipeError
merr of
Maybe RecipeError
Nothing -> []
Just (MissingDependenciesError (MissingDependencies CallStack
_ TypeRep
_ Set TypeRep
missing)) ->
case BeanConstructionStep
step of
PrimaryBean TypeRep
rep
| TypeRep -> Set TypeRep -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member TypeRep
rep Set TypeRep
missing ->
[ String -> Text
Data.Text.pack String
"style" Text -> Text -> Attribute Text
forall s. s -> s -> Attribute s
Dot.:= String -> Text
Data.Text.pack String
"dashed",
String -> Text
Data.Text.pack String
"color" Text -> Text -> Attribute Text
forall s. s -> s -> Attribute s
Dot.:= String -> Text
Data.Text.pack String
"red"
]
BeanConstructionStep
_ -> []
Just (DoubleDutyBeansError (DoubleDutyBeans (Map TypeRep (CallStack, CallStack) -> Set TypeRep
forall k a. Map k a -> Set k
Map.keysSet -> Set TypeRep
bs))) ->
case BeanConstructionStep
step of
PrimaryBean TypeRep
rep
| TypeRep -> Set TypeRep -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member TypeRep
rep Set TypeRep
bs ->
[ String -> Text
Data.Text.pack String
"style" Text -> Text -> Attribute Text
forall s. s -> s -> Attribute s
Dot.:= String -> Text
Data.Text.pack String
"bold",
String -> Text
Data.Text.pack String
"color" Text -> Text -> Attribute Text
forall s. s -> s -> Attribute s
Dot.:= String -> Text
Data.Text.pack String
"green"
]
SecondaryBean TypeRep
rep
| TypeRep -> Set TypeRep -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member TypeRep
rep Set TypeRep
bs ->
[ String -> Text
Data.Text.pack String
"style" Text -> Text -> Attribute Text
forall s. s -> s -> Attribute s
Dot.:= String -> Text
Data.Text.pack String
"bold",
String -> Text
Data.Text.pack String
"color" Text -> Text -> Attribute Text
forall s. s -> s -> Attribute s
Dot.:= String -> Text
Data.Text.pack String
"green"
]
BeanConstructionStep
_ -> []
Just (DependencyCycleError (DependencyCycle (Plan -> Set BeanConstructionStep
forall a. Ord a => [a] -> Set a
Set.fromList (Plan -> Set BeanConstructionStep)
-> (NonEmpty (BeanConstructionStep, Maybe CallStack) -> Plan)
-> NonEmpty (BeanConstructionStep, Maybe CallStack)
-> Set BeanConstructionStep
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Cycle BeanConstructionStep -> Plan
forall a. NonEmpty a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
Data.Foldable.toList (Cycle BeanConstructionStep -> Plan)
-> (NonEmpty (BeanConstructionStep, Maybe CallStack)
-> Cycle BeanConstructionStep)
-> NonEmpty (BeanConstructionStep, Maybe CallStack)
-> Plan
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((BeanConstructionStep, Maybe CallStack) -> BeanConstructionStep)
-> NonEmpty (BeanConstructionStep, Maybe CallStack)
-> Cycle BeanConstructionStep
forall a b. (a -> b) -> NonEmpty a -> NonEmpty b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (BeanConstructionStep, Maybe CallStack) -> BeanConstructionStep
forall a b. (a, b) -> a
fst -> Set BeanConstructionStep
cycleStepSet))) ->
if BeanConstructionStep -> Set BeanConstructionStep -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member BeanConstructionStep
step Set BeanConstructionStep
cycleStepSet
then
[ String -> Text
Data.Text.pack String
"style" Text -> Text -> Attribute Text
forall s. s -> s -> Attribute s
Dot.:= String -> Text
Data.Text.pack String
"bold",
String -> Text
Data.Text.pack String
"color" Text -> Text -> Attribute Text
forall s. s -> s -> Attribute s
Dot.:= String -> Text
Data.Text.pack String
"blue"
]
else []
}
setVertexName :: (BeanConstructionStep -> Data.Text.Text) -> Dot.Style BeanConstructionStep Data.Text.Text -> Dot.Style BeanConstructionStep Data.Text.Text
setVertexName :: (BeanConstructionStep -> Text)
-> Style BeanConstructionStep Text
-> Style BeanConstructionStep Text
setVertexName BeanConstructionStep -> Text
vertexName Style BeanConstructionStep Text
style = Style BeanConstructionStep Text
style {Dot.vertexName}
defaultStepToText :: BeanConstructionStep -> Data.Text.Text
defaultStepToText :: BeanConstructionStep -> Text
defaultStepToText =
let p :: a -> Text
p a
rep = String -> Text
Data.Text.pack do a -> String
forall a. Show a => a -> String
show a
rep
in \case
BarePrimaryBean TypeRep
rep -> TypeRep -> Text
forall {a}. Show a => a -> Text
p TypeRep
rep Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Data.Text.pack String
"#bare"
PrimaryBeanDeco TypeRep
rep Int
index -> TypeRep -> Text
forall {a}. Show a => a -> Text
p TypeRep
rep Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Data.Text.pack (String
"#deco#" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
index)
PrimaryBean TypeRep
rep -> TypeRep -> Text
forall {a}. Show a => a -> Text
p TypeRep
rep
SecondaryBean TypeRep
rep -> TypeRep -> Text
forall {a}. Show a => a -> Text
p TypeRep
rep Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> String -> Text
Data.Text.pack String
"#agg"
nonEmptyToTree :: NonEmpty a -> Tree a
nonEmptyToTree :: forall a. NonEmpty a -> Tree a
nonEmptyToTree = \case
a
a Data.List.NonEmpty.:| [] -> a -> [Tree a] -> Tree a
forall a. a -> [Tree a] -> Tree a
Node a
a []
a
a Data.List.NonEmpty.:| (a
b : [a]
rest) -> a -> [Tree a] -> Tree a
forall a. a -> [Tree a] -> Tree a
Node a
a [NonEmpty a -> Tree a
forall a. NonEmpty a -> Tree a
nonEmptyToTree (a
b a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
Data.List.NonEmpty.:| [a]
rest)]
unsafeTreeToNonEmpty :: Tree a -> NonEmpty a
unsafeTreeToNonEmpty :: forall a. Tree a -> NonEmpty a
unsafeTreeToNonEmpty = \case
Node a
a [] -> a
a a -> [a] -> NonEmpty a
forall a. a -> [a] -> NonEmpty a
Data.List.NonEmpty.:| []
Node a
a [Tree a
b] -> a -> NonEmpty a -> NonEmpty a
forall a. a -> NonEmpty a -> NonEmpty a
Data.List.NonEmpty.cons a
a (Tree a -> NonEmpty a
forall a. Tree a -> NonEmpty a
unsafeTreeToNonEmpty Tree a
b)
Tree a
_ -> String -> NonEmpty a
forall a. HasCallStack => String -> a
error String
"tree not list-shaped"
data Constructor m bean = Constructor
{ forall (m :: * -> *) bean. Constructor m bean -> CallStack
_constructorCallStack :: CallStack,
forall (m :: * -> *) bean.
Constructor m bean -> Args (m (Regs bean))
_args :: Args (m (Regs bean))
}
val_ :: forall bean m. (Applicative m, HasCallStack) => Args bean -> Constructor m bean
val_ :: forall bean (m :: * -> *).
(Applicative m, HasCallStack) =>
Args bean -> Constructor m bean
val_ Args bean
x = CallStack -> Args (m (Regs bean)) -> Constructor m bean
forall (m :: * -> *) bean.
CallStack -> Args (m (Regs bean)) -> Constructor m bean
Constructor CallStack
HasCallStack => CallStack
callStack (Args (m (Regs bean)) -> Constructor m bean)
-> Args (m (Regs bean)) -> Constructor m bean
forall a b. (a -> b) -> a -> b
$ (bean -> m (Regs bean)) -> Args bean -> Args (m (Regs bean))
forall a b. (a -> b) -> Args a -> Args b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Regs bean -> m (Regs bean)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Regs bean -> m (Regs bean))
-> (bean -> Regs bean) -> bean -> m (Regs bean)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. bean -> Regs bean
forall a. a -> Regs a
forall (f :: * -> *) a. Applicative f => a -> f a
pure) Args bean
x
val :: forall {nested} bean m. (Registrable nested bean, Applicative m, HasCallStack) => Args nested -> Constructor m bean
val :: forall {nested} bean (m :: * -> *).
(Registrable nested bean, Applicative m, HasCallStack) =>
Args nested -> Constructor m bean
val Args nested
x = (HasCallStack => Constructor m bean) -> Constructor m bean
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack (Args (Regs bean) -> Constructor m bean
forall bean (m :: * -> *).
(Applicative m, HasCallStack) =>
Args (Regs bean) -> Constructor m bean
val' (Args (Regs bean) -> Constructor m bean)
-> Args (Regs bean) -> Constructor m bean
forall a b. (a -> b) -> a -> b
$ (Identity (Regs bean) -> Regs bean)
-> Args (Identity (Regs bean)) -> Args (Regs bean)
forall a b. (a -> b) -> Args a -> Args b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Identity (Regs bean) -> Regs bean
forall a. Identity a -> a
runIdentity (Args (Identity (Regs bean)) -> Args (Regs bean))
-> Args (Identity (Regs bean)) -> Args (Regs bean)
forall a b. (a -> b) -> a -> b
$ Args (Identity nested) -> Args (Identity (Regs bean))
forall nested tip (m :: * -> *).
(Registrable nested tip, Functor m) =>
Args (m nested) -> Args (m (Regs tip))
forall (m :: * -> *).
Functor m =>
Args (m nested) -> Args (m (Regs bean))
register (Args (Identity nested) -> Args (Identity (Regs bean)))
-> Args (Identity nested) -> Args (Identity (Regs bean))
forall a b. (a -> b) -> a -> b
$ (nested -> Identity nested)
-> Args nested -> Args (Identity nested)
forall a b. (a -> b) -> Args a -> Args b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap nested -> Identity nested
forall a. a -> Identity a
Identity Args nested
x)
val' :: forall bean m. (Applicative m, HasCallStack) => Args (Regs bean) -> Constructor m bean
val' :: forall bean (m :: * -> *).
(Applicative m, HasCallStack) =>
Args (Regs bean) -> Constructor m bean
val' Args (Regs bean)
x = CallStack -> Args (m (Regs bean)) -> Constructor m bean
forall (m :: * -> *) bean.
CallStack -> Args (m (Regs bean)) -> Constructor m bean
Constructor CallStack
HasCallStack => CallStack
callStack (Args (m (Regs bean)) -> Constructor m bean)
-> Args (m (Regs bean)) -> Constructor m bean
forall a b. (a -> b) -> a -> b
$ (Regs bean -> m (Regs bean))
-> Args (Regs bean) -> Args (m (Regs bean))
forall a b. (a -> b) -> Args a -> Args b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Regs bean -> m (Regs bean)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Args (Regs bean)
x
eff_ :: forall bean m. (Functor m, HasCallStack) => Args (m bean) -> Constructor m bean
eff_ :: forall bean (m :: * -> *).
(Functor m, HasCallStack) =>
Args (m bean) -> Constructor m bean
eff_ Args (m bean)
x = CallStack -> Args (m (Regs bean)) -> Constructor m bean
forall (m :: * -> *) bean.
CallStack -> Args (m (Regs bean)) -> Constructor m bean
Constructor CallStack
HasCallStack => CallStack
callStack (Args (m (Regs bean)) -> Constructor m bean)
-> Args (m (Regs bean)) -> Constructor m bean
forall a b. (a -> b) -> a -> b
$ (m bean -> m (Regs bean)) -> Args (m bean) -> Args (m (Regs bean))
forall a b. (a -> b) -> Args a -> Args b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((bean -> Regs bean) -> m bean -> m (Regs bean)
forall a b. (a -> b) -> m a -> m b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap bean -> Regs bean
forall a. a -> Regs a
forall (f :: * -> *) a. Applicative f => a -> f a
pure) Args (m bean)
x
ioEff_ :: forall bean m. (MonadIO m, HasCallStack) => Args (IO bean) -> Constructor m bean
ioEff_ :: forall bean (m :: * -> *).
(MonadIO m, HasCallStack) =>
Args (IO bean) -> Constructor m bean
ioEff_ Args (IO bean)
args = (HasCallStack => Constructor m bean) -> Constructor m bean
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((forall x. IO x -> m x)
-> Constructor IO bean -> Constructor m bean
forall (m :: * -> *) (n :: * -> *) bean.
(forall x. m x -> n x) -> Constructor m bean -> Constructor n bean
hoistConstructor IO x -> m x
forall x. IO x -> m x
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Args (IO bean) -> Constructor IO bean
forall bean (m :: * -> *).
(Functor m, HasCallStack) =>
Args (m bean) -> Constructor m bean
eff_ Args (IO bean)
args))
eff :: forall {nested} bean m. (Registrable nested bean, Monad m, HasCallStack) => Args (m nested) -> Constructor m bean
eff :: forall {nested} bean (m :: * -> *).
(Registrable nested bean, Monad m, HasCallStack) =>
Args (m nested) -> Constructor m bean
eff Args (m nested)
x = (HasCallStack => Constructor m bean) -> Constructor m bean
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack (Args (m (Regs bean)) -> Constructor m bean
forall bean (m :: * -> *).
HasCallStack =>
Args (m (Regs bean)) -> Constructor m bean
eff' (Args (m (Regs bean)) -> Constructor m bean)
-> Args (m (Regs bean)) -> Constructor m bean
forall a b. (a -> b) -> a -> b
$ Args (m nested) -> Args (m (Regs bean))
forall nested tip (m :: * -> *).
(Registrable nested tip, Functor m) =>
Args (m nested) -> Args (m (Regs tip))
forall (m :: * -> *).
Functor m =>
Args (m nested) -> Args (m (Regs bean))
register Args (m nested)
x)
ioEff :: forall {nested} bean m. (Registrable nested bean, MonadIO m, HasCallStack) => Args (IO nested) -> Constructor m bean
ioEff :: forall {nested} bean (m :: * -> *).
(Registrable nested bean, MonadIO m, HasCallStack) =>
Args (IO nested) -> Constructor m bean
ioEff Args (IO nested)
args = (HasCallStack => Constructor m bean) -> Constructor m bean
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((forall x. IO x -> m x)
-> Constructor IO bean -> Constructor m bean
forall (m :: * -> *) (n :: * -> *) bean.
(forall x. m x -> n x) -> Constructor m bean -> Constructor n bean
hoistConstructor IO x -> m x
forall x. IO x -> m x
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Args (IO nested) -> Constructor IO bean
forall {nested} bean (m :: * -> *).
(Registrable nested bean, Monad m, HasCallStack) =>
Args (m nested) -> Constructor m bean
eff Args (IO nested)
args))
eff' :: forall bean m. (HasCallStack) => Args (m (Regs bean)) -> Constructor m bean
eff' :: forall bean (m :: * -> *).
HasCallStack =>
Args (m (Regs bean)) -> Constructor m bean
eff' = CallStack -> Args (m (Regs bean)) -> Constructor m bean
forall (m :: * -> *) bean.
CallStack -> Args (m (Regs bean)) -> Constructor m bean
Constructor CallStack
HasCallStack => CallStack
callStack
runConstructor :: (Monad m) => [Beans] -> Constructor m bean -> m (Beans, bean)
runConstructor :: forall (m :: * -> *) bean.
Monad m =>
[Beans] -> Constructor m bean -> m (Beans, bean)
runConstructor [Beans]
bss (Constructor {Args (m (Regs bean))
_args :: forall (m :: * -> *) bean.
Constructor m bean -> Args (m (Regs bean))
_args :: Args (m (Regs bean))
_args}) = do
regs <- Args (m (Regs bean))
_args Args (m (Regs bean))
-> (Args (m (Regs bean)) -> m (Regs bean)) -> m (Regs bean)
forall a b. a -> (a -> b) -> b
& (forall b. Typeable b => Maybe b)
-> Args (m (Regs bean)) -> m (Regs bean)
forall a. (forall b. Typeable b => Maybe b) -> Args a -> a
runArgs ([Maybe b] -> Maybe b
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
Data.Foldable.asum (Beans -> Maybe b
forall bean. Typeable bean => Beans -> Maybe bean
taste (Beans -> Maybe b) -> [Beans] -> [Maybe b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Beans]
bss))
pure (runRegs (getRegsReps _args) regs)
hoistConstructor :: (forall x. m x -> n x) -> Constructor m bean -> Constructor n bean
hoistConstructor :: forall (m :: * -> *) (n :: * -> *) bean.
(forall x. m x -> n x) -> Constructor m bean -> Constructor n bean
hoistConstructor forall x. m x -> n x
f c :: Constructor m bean
c@Constructor {Args (m (Regs bean))
_args :: forall (m :: * -> *) bean.
Constructor m bean -> Args (m (Regs bean))
_args :: Args (m (Regs bean))
_args} = Constructor m bean
c {_args = fmap f _args}
hoistConstructor' :: (Args (m (Regs bean)) -> Args (n (Regs bean))) -> Constructor m bean -> Constructor n bean
hoistConstructor' :: forall (m :: * -> *) bean (n :: * -> *).
(Args (m (Regs bean)) -> Args (n (Regs bean)))
-> Constructor m bean -> Constructor n bean
hoistConstructor' Args (m (Regs bean)) -> Args (n (Regs bean))
f c :: Constructor m bean
c@Constructor {Args (m (Regs bean))
_args :: forall (m :: * -> *) bean.
Constructor m bean -> Args (m (Regs bean))
_args :: Args (m (Regs bean))
_args} = Constructor m bean
c {_args = f _args}
getConstructorArgs :: Constructor m bean -> Args (m (Regs bean))
getConstructorArgs :: forall (m :: * -> *) bean.
Constructor m bean -> Args (m (Regs bean))
getConstructorArgs (Constructor {Args (m (Regs bean))
_args :: forall (m :: * -> *) bean.
Constructor m bean -> Args (m (Regs bean))
_args :: Args (m (Regs bean))
_args}) = Args (m (Regs bean))
_args
getConstructorCallStack :: Constructor m bean -> CallStack
getConstructorCallStack :: forall (m :: * -> *) bean. Constructor m bean -> CallStack
getConstructorCallStack (Constructor {CallStack
_constructorCallStack :: forall (m :: * -> *) bean. Constructor m bean -> CallStack
_constructorCallStack :: CallStack
_constructorCallStack}) = CallStack
_constructorCallStack
getRecipeCallStack :: SomeRecipe m -> CallStack
getRecipeCallStack :: forall (m :: * -> *). SomeRecipe m -> CallStack
getRecipeCallStack (SomeRecipe {CallStack
_recipeCallStack :: forall (m :: * -> *). SomeRecipe m -> CallStack
_recipeCallStack :: CallStack
_recipeCallStack}) = CallStack
_recipeCallStack
keysSet :: Cauldron m -> Set TypeRep
keysSet :: forall (m :: * -> *). Cauldron m -> Set TypeRep
keysSet Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap} = Map TypeRep (SomeRecipe m) -> Set TypeRep
forall k a. Map k a -> Set k
Map.keysSet Map TypeRep (SomeRecipe m)
recipeMap
restrictKeys :: Cauldron m -> Set TypeRep -> Cauldron m
restrictKeys :: forall (m :: * -> *). Cauldron m -> Set TypeRep -> Cauldron m
restrictKeys Cauldron {Map TypeRep (SomeRecipe m)
recipeMap :: forall (m :: * -> *). Cauldron m -> Map TypeRep (SomeRecipe m)
recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap} Set TypeRep
trs = Cauldron {recipeMap :: Map TypeRep (SomeRecipe m)
recipeMap = Map TypeRep (SomeRecipe m)
-> Set TypeRep -> Map TypeRep (SomeRecipe m)
forall k a. Ord k => Map k a -> Set k -> Map k a
Map.restrictKeys Map TypeRep (SomeRecipe m)
recipeMap Set TypeRep
trs}