Основная идея заключается в том, что у меня есть ряд функций, которые работают с любыми типами из определенного класса, но во время выполнения программа должна считывать файл конфигурации и извлекать элемент одного из типов в классе.
Например, у меня есть класс 'Coefficient', различные его экземпляры и функции различных типов, которые полиморфны над типами этого класса; во время выполнения должен быть определен и передан один конкретный тип этого класса.
Я не уверен, как правильно решить эту проблему; Я пытался составить «составные» типы, делая что-то вроде:
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, если я действительно составляю составной тип ColourData.
Я также изучил Data.Dynamic, но, опять же, я не вижу, как он будет правильно решать проблемы; точно такие же проблемы появляются (ну, даже немного хуже, учитывая, что, как я понимаю, существует только один «универсальный» динамический тип).
Вопрос: Как я могу реализовать динамические типы данных, подчиненные определенным классам, без необходимости переписывать все функции, включающие эти типы данных? Было бы лучше, если бы мне не пришлось жертвовать какой-либо типовой безопасностью, но я не слишком оптимистичен.
Предполагается, что программа читает файл конфигурации во время выполнения, и должны быть применены все необходимые функции, полиморфные по отношению к соответствующему классу.