json – Haskell Aeson:如何将Value转换为自定义类型?

前端之家收集整理的这篇文章主要介绍了json – Haskell Aeson:如何将Value转换为自定义类型?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
找不到一个好例子.感谢任何帮助. JSON如下:
  1. [{
  2. "EXIF:Make": "Canon","EXIF:Model": "Canon PowerShot S95","EXIF:Orientation": "Horizontal (normal)","EXIF:XResolution": 180,"EXIF:YResolution": 180,"EXIF:ResolutionUnit": "inches"
  3. }]

我使用的代码如下:

  1. import Data.Aeson
  2. import Data.Attoparsec
  3. import Data.ByteString
  4. x <- fmap (parse json) (Data.ByteString.readFile "json.txt")

我该如何定义&使用FromJSON类型从x转换为:

  1. data Exif = Exif [[(String,String)]]

或类似的数据结构?注意[[]] – 我希望JSON有多个顶级条目.

解决方法

这是一个惯用的解决方案:
  1. {-# LANGUAGE OverloadedStrings #-}
  2.  
  3. module Main
  4. where
  5.  
  6. import Control.Applicative
  7. import Control.Monad
  8. import Data.Aeson
  9. import Data.Attoparsec
  10.  
  11. import qualified Data.ByteString as B
  12. import qualified Data.Text as T
  13.  
  14. data ExifEntry = ExifEntry { exifMake :: T.Text,exifModel :: T.Text,exifOrientation :: T.Text,exifXResolution :: Int,exifYResolution :: Int,exifResolutionUnit :: T.Text
  15. } deriving (Eq,Show)
  16.  
  17.  
  18. instance FromJSON ExifEntry
  19. where
  20. parseJSON (Object v) = ExifEntry <$>
  21. v .: "EXIF:Make" <*>
  22. v .: "EXIF:Model" <*>
  23. v .: "EXIF:Orientation" <*>
  24. v .: "EXIF:XResolution" <*>
  25. v .: "EXIF:YResolution" <*>
  26. v .: "EXIF:ResolutionUnit"
  27. parseJSON _ = mzero
  28.  
  29.  
  30. parseAll :: B.ByteString -> [ExifEntry]
  31. parseAll s = case (parse (fromJSON <$> json) s) of
  32. Done _ (Error err) -> error err
  33. Done ss (Success e) -> e:(parseAll ss)
  34. _ -> []
  35.  
  36. main :: IO ()
  37. main = do s <- B.readFile "json.txt"
  38. let p = parseAll s
  39. print p

测试:

  1. $cat json.txt
  2. {
  3. "EXIF:Make": "Canon","EXIF:ResolutionUnit": "inches"
  4. }
  5.  
  6. {
  7. "EXIF:Make": "Canon","EXIF:Model": "Canon PowerShot S995","EXIF:ResolutionUnit": "inches"
  8. }
  9. $./dist/build/test/test
  10. [ExifEntry {exifMake = "Canon",exifModel = "Canon PowerShot S95",exifOrientation = "Horizontal (normal)",exifXResolution = 180,exifYResolution = 180,exifResolutionUnit = "inches"},ExifEntry {exifMake = "Canon",exifModel = "Canon PowerShot S995",exifResolutionUnit = "inches"}]

或者,这是一个slightly more ugly solution,它为您提供所请求的数据类型([[(Text,Text)]]).

猜你在找的JavaScript相关文章