2013-09-23 228 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" } 

解碼。