LINUX.ORG.RU

Хаскель - парсим произвольный тип


0

0

Изначально задача звучала так - сохранять и читать список опций (любого типа).
Для ее решения потребовался динамический тип, который умеет 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)
★★

Ответ на: комментарий от Begemoth

В первом и третьем случае классами типов не обойтись, поскольку тип будет известен только во время выполнения.

Из hs-plugins самый простой вариант - eval.

Begemoth ★★★★★
()
Ответ на: комментарий от Begemoth

Да, скорее всего реализую через plugins, хотя eval достаточно медленная штука... Обычными средствами вроде вообще никак, в Typeable/Dynamic нет конструктора типов по названию.

AiLr ★★
() автор топика
Ответ на: комментарий от AiLr

Для решения задачи без плагинов нужна фабрика объектов - можно сначала создать (Read a) => Map.Map String (String -> a), а парсер конфига запихнуть в MonadReader.

Как варинант конфигов - конфиг может быть сам хаскелным модулем (динамически загружаемым).

Begemoth ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.