{-# LANGUAGE AllowAmbiguousTypes #-}
module Data.Registry.Internal.Dynamic where
import Data.Dynamic
import Data.Registry.Internal.Types
import Data.Text
import Protolude
import Type.Reflection
applyFunction ::
Function
-> [Value]
-> Either Text Value
applyFunction function values =
do created <- applyFunctionDyn (funDyn function) (valueDyn <$> values)
pure $ CreatedValue created (ValueDescription (_outputType . funDescription $ function) Nothing)
applyFunctionDyn
:: Dynamic
-> [Dynamic]
-> Either Text Dynamic
applyFunctionDyn f [] =
Left $ "the function "
<> show (dynTypeRep f)
<> " cannot be applied to an empty list of parameters"
applyFunctionDyn f [i ] = applyOneParam f i
applyFunctionDyn f (i : is) = do
f' <- applyOneParam f i
applyFunctionDyn f' is
applyOneParam :: Dynamic -> Dynamic -> Either Text Dynamic
applyOneParam f i =
maybe (Left $ "failed to apply " <> show i <> " to : " <> show f) Right (dynApply f i)
collectInputTypes :: Function -> [SomeTypeRep]
collectInputTypes = go . funDynTypeRep
where
go :: SomeTypeRep -> [SomeTypeRep]
go (SomeTypeRep (Fun in1 out)) = SomeTypeRep in1 : go (SomeTypeRep out)
go _ = []
outputType :: SomeTypeRep -> SomeTypeRep
outputType (SomeTypeRep (Fun _ out)) = outputType (SomeTypeRep out)
outputType r = r