本文介绍了Haskell Aeson:如何将Value转换为自定义类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 找不到一个好例子。感谢任何帮助。 JSON如下: [{EXIF:Make:Canon, EXIF:Model:Canon PowerShot S95,EXIF:Orientation:水平(普通),EXIF:XResolution:180,EXIF:YResolution :180,EXIF:ResolutionUnit:inches}] 我使用的代码如下: import Data.Aeson import Data.Attoparsec import Data.ByteString x< - fmap(parse json)(Data.ByteString.readFilejson.txt) 如何定义&使用 FromJSON 类型从 x 转换为: data Exif = Exif [[(String,String)]] [[]] - 我期待JSON有多个顶级条目。 解决方案以下是一个惯用的解决方案: { - #LANGUAGE OverloadedStrings# - } 模块主要其中 导入Control.Applicative 导入Control.Monad 导入Data.Aeson 导入Data.Attoparsec 将合格的Data.ByteString导入为B 将合格的Data.Text导入为T 数据ExifEntry = ExifEntry {exifMake :: T.Text, exifModel: :T.Text, exifOrientation :: T.Text, exifXResolution :: Int, exifYResolution :: Int, exifResolutionUnit :: T.Text }派生(Eq,Show) 实例FromJSON ExifEntry 其中 parseJSON(Object v)= ExifEntry< $> v。:EXIF:Make< *> v。:EXIF:Model< *> v。:EXIF:Orientation< *> v。:EXIF:XResolution< *> v。:EXIF:YResolution< *> v。:EXIF:ResolutionUnit parseJSON _ = mzero parseAll :: B.ByteString - > [ExifEntry] parseAll s = case(解析(fromJSON< $> json)s)完成_(错误错误) - >错误错误完成ss(成功e) - > e:(parseAll ss) _ - > [] main :: IO() main = do s let p = parseAll s print p 测试: {EXIF:Make:Canon,EXIF:Model:Canon PowerShot S95, EXIF:Orientation:Horizontal(normal),EXIF:XResolution:180,EXIF:YResolution:180,EXIF:ResolutionUnit:inches $ bEXIF:Make:Canon,EXIF:Model:Canon PowerShot S995,EXIF:方向:水平(普通),EXIF:X分辨率:180,EXIF:Y分辨率:180,EXIF:ResolutionUnit:英寸$ b $ [ExifEntry {exifMake =Canon,exifModel =Canon PowerShot S95,exifOrientation =Horizontal(normal),exifXResolution = 180, exifYResolution = 180,exifResolutionUnit =inches},ExifEntry {exifMake =Canon,exifModel =Canon PowerShot S995,exifOrient ation =Horizontal(normal),exifXResolution = 180,exifYResolution = 180,exifResolutionUnit =inches}] 或者,这里有一个稍微更难看的解决方案,它为您提供了您请求的数据类型( [[ (Text,Text)]] )。 Can't find a good example. Appreciate any help. The JSON is as follows:[{ "EXIF:Make": "Canon", "EXIF:Model": "Canon PowerShot S95", "EXIF:Orientation": "Horizontal (normal)", "EXIF:XResolution": 180, "EXIF:YResolution": 180, "EXIF:ResolutionUnit": "inches"}]The code I used is as follows:import Data.Aesonimport Data.Attoparsecimport Data.ByteStringx <- fmap (parse json) (Data.ByteString.readFile "json.txt")How do I define & use the FromJSON type to convert from x into:data Exif = Exif [[(String, String)]]or similar data structure? Note the [[]] -- I'm expecting the JSON to have multiple top-level entries. 解决方案 Here's an idiomatic solution:{-# LANGUAGE OverloadedStrings #-}module Main whereimport Control.Applicativeimport Control.Monadimport Data.Aesonimport Data.Attoparsecimport qualified Data.ByteString as Bimport qualified Data.Text as Tdata ExifEntry = ExifEntry { exifMake :: T.Text, exifModel :: T.Text, exifOrientation :: T.Text, exifXResolution :: Int, exifYResolution :: Int, exifResolutionUnit :: T.Text } deriving (Eq, Show)instance FromJSON ExifEntry where parseJSON (Object v) = ExifEntry <$> v .: "EXIF:Make" <*> v .: "EXIF:Model" <*> v .: "EXIF:Orientation" <*> v .: "EXIF:XResolution" <*> v .: "EXIF:YResolution" <*> v .: "EXIF:ResolutionUnit" parseJSON _ = mzeroparseAll :: B.ByteString -> [ExifEntry]parseAll s = case (parse (fromJSON <$> json) s) of Done _ (Error err) -> error err Done ss (Success e) -> e:(parseAll ss) _ -> []main :: IO ()main = do s <- B.readFile "json.txt" let p = parseAll s print pTesting:$ cat json.txt{ "EXIF:Make": "Canon", "EXIF:Model": "Canon PowerShot S95", "EXIF:Orientation": "Horizontal (normal)", "EXIF:XResolution": 180, "EXIF:YResolution": 180, "EXIF:ResolutionUnit": "inches"}{ "EXIF:Make": "Canon", "EXIF:Model": "Canon PowerShot S995", "EXIF:Orientation": "Horizontal (normal)", "EXIF:XResolution": 180, "EXIF:YResolution": 180, "EXIF:ResolutionUnit": "inches"}$ ./dist/build/test/test[ExifEntry {exifMake = "Canon", exifModel = "Canon PowerShot S95", exifOrientation = "Horizontal (normal)", exifXResolution = 180, exifYResolution = 180, exifResolutionUnit = "inches"},ExifEntry {exifMake = "Canon", exifModel = "Canon PowerShot S995", exifOrientation = "Horizontal (normal)", exifXResolution = 180, exifYResolution = 180, exifResolutionUnit = "inches"}]Alternatively, here's a slightly more ugly solution that gives you the data type you requested ([[(Text,Text)]]). 这篇关于Haskell Aeson:如何将Value转换为自定义类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 08-14 14:12