2013-09-23 3 views
1

Например, есть такой JSon файл с некоторыми лицами (модули):разбора пользовательских алгебраический тип данных из JSON

{ 
    "name" : "module1", 
    "type" : "Type1" 
}, 

{ 
    "name" : "module2", 
    "type" : "Type2" 
} 

И я хочу, чтобы построить свой тип данных модуля из этого JSON

data Module = Module {name::String, type :: ModuleType} 

data ModuleType = Type1 | Type2 

Что такое самый удобный способ создания такого типа данных из json? Как я могу анализировать мои пользовательские типы Type1 и Type2, преобразовывать и проверять их? Любая помощь будет оценена =)

ответ

3

Я рекомендую вам использовать удивительный модуль aeson. Это очень быстро, очень легко понять, и вы можете быстро развить логику синтаксического анализа. В начале страницы есть несколько примеров, и вы можете использовать этот пример 99% в своем коде.

instance FromJSON Module where 
    parseJSON (Object v) = build <$> 
          v .: "name" <*> 
          v .: "type" 
    -- A non-Object value is of the wrong type, so fail. 
    parseJSON _   = mzero 

build :: String -> String -> Module 
build name "Type1" = Module name Type1 
build name "Type2" = Module name Type2 
+0

Спасибо, я уже посмотрел на него. И это первый пример показывает, как обрабатывать тип данных Person, который имеет свойства Int и Text, можете ли вы указать, как реализовать синтаксический анализ моего настраиваемого типа данных таким образом, в моем случае ModuleType? – AlexMost

+0

Вы можете использовать этот пример, без каких-либо изменений помимо включения значения 'type', чтобы выбрать подходящий конструктор. –

+0

извините, но не могу решить, как писать экземпляр FromJSON для моего модуля, вы можете предоставить фрагмент кода? – AlexMost

0

В идеале, вы хотите, чтобы написать свой собственный FromJSON экземпляр для ModuleType типа данных:

instance FromJSON Module where 
    parseJSON (Object v) = Module <$> 
          v .: "name" <*> 
          v .: "type" 
    parseJSON _   = mzero 

instance FromJSON ModuleType where 
    parseJSON (String t) = case t of 
           "Type1" -> return Type1 
           "Type2" -> return Type2 
           _  -> mzero 
    parseJSON _   = mzero 

Таким образом, вы не столкнетесь с non-exhaustive pattern ошибок (как это может произойти с решением Михая), когда кто-то дает вы как строка

{ "name": "module1", "type": "unconventional-type" } 

для декодирования.

Смежные вопросы