Изначально задача звучала так - сохранять и читать список опций (любого типа).
Для ее решения потребовался динамический тип, который умеет show и read, и при этом выглядеть результат show должен являться обычным кодом на хаскелле.
Короче хочется чтобы show (Foo 5) давал "(5::Int)", show (Foo 2.4) - "(2.4::Double)", show (Foo "abc") - "(\"abc\"::[Char]), а read это читал. первый я реализовал так
data VDyn = forall a. (Read a, Show a, Typeable a)
=> VDyn a
instance Show VDyn
where
showsPrec _ (VDyn a) = showString $
"("
++ (show a)
++ "::"
++ (show $ typeOf a)
++ ")"
А вот с read'ом напряг, тк тип записан после данных :( Если кто поможет буду очень признателен ;) (желательно парсить стандартными средствами как в GHC.Read)
Да, скорее всего реализую через plugins, хотя eval достаточно медленная штука... Обычными средствами вроде вообще никак, в Typeable/Dynamic нет конструктора типов по названию.
Для решения задачи без плагинов нужна фабрика объектов - можно сначала создать (Read a) => Map.Map String (String -> a), а парсер конфига запихнуть в MonadReader.
Как варинант конфигов - конфиг может быть сам хаскелным модулем (динамически загружаемым).