Основная идея состоит в том, что у меня есть ряд функций, которые работают с любыми типами из определенного класса, но во время выполнения программа должна читать файл конфигурации и извлечь элемент одного из типов в классе.
Например, у меня есть класс «Коэффициент», различные его экземпляры и функции различных типов, которые полиморфны по отношению к типам этого класса; во время выполнения должен быть определен и передан один конкретный тип этого класса.
Я не знаю, как правильно решить эту проблему; Я попытался создать «составные» типы, выполнив что-то вроде:
data CompoundCoeff = CompoundInt Int | CompoundDouble Double | ...
где Int, Double, ... являются экземплярами класса «Коэффициент».
Однако адаптация всех функций, задействованных в коде, для работы с этими составными типами требует значительных усилий (на самом деле это тоже не очень хорошее решение). Было бы хорошо, если бы все функции имели один и тот же простой тип, например.
Coefficient a => a -> (stuff not involving a anymore)
но, к сожалению, это не так.
Еще одна проблема, с которой я столкнулся, заключается в том, что я использую семейства типов и имею что-то вроде
class (Monoid (ColourData c), Coordinate (InputData c)) => ColourScheme c where
type ColourData c :: *
type InputData c :: *
colouriseData :: c -> (ColourData c) -> AlphaColour Double
processInput :: c -> InputData c -> ColourData c
Это не проходит чисто, если мне приходится использовать какой-то составной тип данных ColourData, подобный предыдущему; в частности, я больше не могу гарантировать, что поток данных дает согласованный тип (а не просто разные «подтипы» составного типа), и (помимо прочего) должен был бы создать фиктивный экземпляр Monoid, если бы я создал составной тип ColorData.
Я также изучил Data.Dynamic, но снова не вижу, как он правильно решит проблемы; похоже, появляются точно такие же проблемы (ну, даже немного хуже, учитывая, что, насколько я понимаю, существует только один «общий» динамический тип).
Вопрос:Как я могу реализовать динамические типы данных, подчиненные определенным классам, без необходимости переписывать все функции, использующие эти типы данных? Было бы лучше, если бы мне не пришлось жертвовать безопасностью типов, но я не слишком оптимистичен.
Предполагается, что программа во время выполнения читает конфигурационный файл, и должны применяться все необходимые функции, полиморфные над соответствующим классом.