2013-09-23 171 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

谢谢,我已经看过它。它的第一个例子显示了如何解析具有Int和Text属性的Person数据类型,你能指出如何以这种方式实现解析我的自定义数据类型,在我的情况下是ModuleType? – AlexMost

+0

您可以使用该示例,在切换“type”的值以选择正确的构造函数之前不需要进行任何更改。 –

+0

抱歉,但无法处理如何为我的ModuleType编写实例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" } 

解码。