Я пытаюсь создать функцию для генерации строкового представления эффектов во время выполнения.
- в общем модуле
... definitions for TestConfig, RunConfig
data GenericTest tc rc i effs as vs = GenericTest {
configuration :: tc,
components :: ItemClass i vs => TestComponents rc i effs as vs
} deriving Typeable
type Test = GenericTest TestConfig RunConfig
type EFFLogger effs = Member Logger effs
type EFFFileSystem effs = Members '[Logger, Ensure, FileSystem] effs
- дочерний модуль 1
.... definitions for items, iterator etc
type Effects effs = EFFFileSystem effs
test :: forall effs. Effects effs => Test Item effs ApState ValState
test = GenericTest {
configuration = config {address = moduleOf ''ApState},
components = TestComponents {
testItems = items,
testInteractor = interactor,
testPrepState = prepState
}
}
- Дочерний модуль 2 (аналогично модулю 1, но с разными эффектами)
.... definitions for items, iterator etc
type Effects effs = EFFLogger effs
test :: forall effs. Effects effs => Test Item effs ApState ValState
test = GenericTest {
configuration = config {address = moduleOf ''ApState},
components = TestComponents {
testItems = items,
testInteractor = interactor,
testPrepState = prepState
}
}
Во время выполнения я хочу функцию f
такую, что:
> f ChildMod1.test
> ["Logger", "Ensure", "FileSystem"]
>
> f ChildMod2.test
> ["Logger"]
Из repl с загруженным дочерним модулем 1 я могу получить следующее, чего, если бы я мог получить что-то похожее в неинтерпретированном коде, было бы достаточно, чтобы получить то, что я хочу:
> :t test
> test
:: (Data.OpenUnion.Internal.FindElem Logger effs,
Data.OpenUnion.Internal.FindElem Ensure effs,
Data.OpenUnion.Internal.FindElem FileSystem effs) =>
Test Item effs ApState ValState
Я пытался использовать Typeableкак предлагается в следующем:
Как я могу прочитать метаданные типа во время выполнения?
, но typeOf дает мне проблемы, которые я понятия не имею, как решить:
> typeOf test
<interactive>:5:1-11: error:
* No instance for (Typeable effs0) arising from a use of `typeOf'
* In the expression: typeOf test
In an equation for `it': it = typeOf test
<interactive>:5:8-11: error:
* Ambiguous type variable `effs0' arising from a use of `test'
prevents the constraint `(Data.OpenUnion.Internal.FindElem
Logger effs0)' from being solved.
Probable fix: use a type annotation to specify what `effs0' should be.
These potential instances exist:
two instances involving out-of-scope types
instance [overlappable] Data.OpenUnion.Internal.FindElem t r =>
Data.OpenUnion.Internal.FindElem t (t' : r)
-- Defined in `Data.OpenUnion.Internal'
instance Data.OpenUnion.Internal.FindElem t (t : r)
-- Defined in `Data.OpenUnion.Internal'
* In the first argument of `typeOf', namely `test'
In the expression: typeOf test
In an equation for `it': it = typeOf test