Haskell、Aeson&;JSON解析为自定义类型

Haskell、Aeson&;JSON解析为自定义类型,json,haskell,aeson,Json,Haskell,Aeson,从一开始,我发现我完全被卡住了。我试图将一个JSON结构解析为我自己的类型,但我不仅停留在如何解析数组上,甚至不确定我是否按照预期使用了Aeson库。任何帮助都将不胜感激 守则: data Exif = Exif [(T.Text, ExifValue)] deriving (Show) data ExifValue = ExifText T.Text | ExifInt Integer | ExifDouble Double | ExifBool Boo

从一开始,我发现我完全被卡住了。我试图将一个JSON结构解析为我自己的类型,但我不仅停留在如何解析数组上,甚至不确定我是否按照预期使用了Aeson库。任何帮助都将不胜感激

守则:

data Exif = Exif [(T.Text, ExifValue)] deriving (Show)
data ExifValue = 
    ExifText T.Text | 
    ExifInt Integer | 
    ExifDouble Double | 
    ExifBool Bool | 
    ExifArray [ExifValue] 
    deriving (Show)

instance FromJSON ExifValue where
    parseJSON (Number (I n)) = return $ ExifInt n
    parseJSON (Number (D n)) = return $ ExifDouble n
    parseJSON (String s)     = return $ ExifText s
    parseJSON (Bool b)       = return $ ExifBool b
    -- parseJSON (Array a)      = ?????

instance FromJSON Exif where
    parseJSON (Object o) = do
        x <- sequence $ map f (M.assocs o)
        return $ Exif x
        where 
        f (t, x) = do
            y <- parseJSON x 
            return ((t, y) :: (T.Text, ExifValue))

parseExifFile = fmap parseExifData . B.readFile

parseExifData :: B.ByteString -> Data.Attoparsec.Result (Data.Aeson.Result [Exif])
parseExifData content = parse (fmap fromJSON json) content

您必须稍微遵循
parseJSON
的类型,但是一旦您认识到
(数组a)
所代表的内容,就应该很简单了

parseJSON
具有类型
Value->Parser a
,因此
(数组a)
具有类型
Value
类型中的一个变量是
数组
,因此
(数组a)
中的
a
必须是
数组
类型,定义为
向量值
向量
中的
是您想要调用的
parseJSON
来返回列表,因此请查看您可以使用

最简单的方法可能是将
a
转换为带有
Vector.toList
的列表,然后使用
mapM
解析


或者,您可以通过将
ExifArray
变量更改为保持
Vector ExifValue
,然后使用
Vector.mapM

来避免
Vector
到列表的转换,因为我不是英语母语,所以可能无法很好地理解您。我猜您想知道如何将json解析为递归数据类型,如您介绍的
ExifValue
。 因此,我制作了一个简单的示例来演示如何将json解析为递归数据类型

{-# LANGUAGE OverloadedStrings #-}
import qualified Data.ByteString as B
import Data.Maybe
import Control.Monad
import Control.Applicative
import Data.Attoparsec
import Data.Attoparsec.Number
import Data.Aeson
import qualified Data.Vector as V

data Data = D1 Int | D2 [Data]
    deriving (Show)

instance FromJSON Data where
    parseJSON (Number (I n)) = return $ D1 $ fromInteger n
    parseJSON (Array a)    = D2 <$> mapM parseJSON (V.toList a)

main = do
    let v = fromJust $ maybeResult $ parse json "[1,2,3,[5,3,[6,3,5]]]"
    let v1 :: Data
        v1 = case fromJSON v of
                 Success a -> a
                 Error s   -> error s
    print v1
{-#语言重载字符串}
将限定数据.ByteString作为B导入
导入数据,也许吧
进口管制
导入控制
导入数据
导入Data.c.Number
导入数据.Aeson
导入符合条件的数据。向量为V
数据数据=D1 Int | D2[数据]
派生(显示)
实例FromJSON数据,其中
parseJSON(Number(in))=从整数n返回$D1$from
parseJSON(数组a)=D2 mapM parseJSON(V.toList a)
main=do
让v=fromJust$maybeResult$parse json“[1,2,3,5,3,6,3,5]]”
让v1::数据
v1=第五种情况
成功a->a
错误s->错误s
打印v1

稍新的版本支持自动生成JSON实例

{-# LANGUAGE TemplateHaskell #-}

import Data.Aeson
import Data.Aeson.TH (deriveJSON)
import Data.Attoparsec
import qualified Data.ByteString as B
import qualified Data.Text as T

data Exif = Exif [(T.Text, ExifValue)] deriving (Show)
data ExifValue = 
    ExifText T.Text | 
    ExifInt Integer | 
    ExifDouble Double | 
    ExifBool Bool | 
    ExifArray [ExifValue] 
    deriving (Show)

deriveJSON id ''Exif
deriveJSON id ''ExifValue

parseExifFile = fmap parseExifData . B.readFile

parseExifData :: B.ByteString -> Data.Attoparsec.Result (Data.Aeson.Result [Exif])
parseExifData content = parse (fmap fromJSON json) content
产生:

instance ToJSON Exif where
  { toJSON
      = \ value_a1Va
          -> case value_a1Va of { Exif arg1_a1Vb -> toJSON arg1_a1Vb } }
instance FromJSON Exif where
  { parseJSON
      = \ value_a1Vc
          -> case value_a1Vc of {
               arg_a1Vd -> (Exif Data.Functor.<$> parseJSON arg_a1Vd) } }

instance ToJSON ExifValue where
  { toJSON
      = \ value_a1Wd
          -> case value_a1Wd of {
               ExifText arg1_a1We
                 -> object [(T.pack "ExifText" .= toJSON arg1_a1We)]
               ExifInt arg1_a1Wf
                 -> object [(T.pack "ExifInt" .= toJSON arg1_a1Wf)]
               ExifDouble arg1_a1Wg
                 -> object [(T.pack "ExifDouble" .= toJSON arg1_a1Wg)]
               ExifBool arg1_a1Wh
                 -> object [(T.pack "ExifBool" .= toJSON arg1_a1Wh)]
               ExifArray arg1_a1Wi
                 -> object [(T.pack "ExifArray" .= toJSON arg1_a1Wi)] } }
instance FromJSON ExifValue where
  { parseJSON
      = \ value_a1Wj
          -> case value_a1Wj of {
               Object obj_a1Wk
                 -> case Data.Map.toList obj_a1Wk of {
                      [(conKey_a1Wl, conVal_a1Wm)]
                        -> case conKey_a1Wl of {
                             _ | (conKey_a1Wl == T.pack "ExifText")
                               -> case conVal_a1Wm of {
                                    arg_a1Wn
                                      -> (ExifText Data.Functor.<$> parseJSON arg_a1Wn) }
                               | (conKey_a1Wl == T.pack "ExifInt")
                               -> case conVal_a1Wm of {
                                    arg_a1Wo
                                      -> (ExifInt Data.Functor.<$> parseJSON arg_a1Wo) }
                               | (conKey_a1Wl == T.pack "ExifDouble")
                               -> case conVal_a1Wm of {
                                    arg_a1Wp
                                      -> (ExifDouble Data.Functor.<$> parseJSON arg_a1Wp) }
                               | (conKey_a1Wl == T.pack "ExifBool")
                               -> case conVal_a1Wm of {
                                    arg_a1Wq
                                      -> (ExifBool Data.Functor.<$> parseJSON arg_a1Wq) }
                               | (conKey_a1Wl == T.pack "ExifArray")
                               -> case conVal_a1Wm of {
                                    arg_a1Wr
                                      -> (ExifArray Data.Functor.<$> parseJSON arg_a1Wr) }
                               | otherwise -> Control.Monad.mzero }
                      _ -> Control.Monad.mzero }
               _ -> Control.Monad.mzero } }
实例ToJSON Exif,其中
{toJSON
=\value\u a1Va
->{Exif arg1\u a1Vb->toJSON arg1\u a1Vb}的大小写值\u a1Va
来自JSON Exif的实例,其中
{parseJSON
=\value\u a1Vc
->案例值\u a1Vc{
arg_a1Vd->(Exif Data.Functor.parseJSON arg_a1Vd)}
实例ToJSON ExifValue,其中
{toJSON
=\value\u a1Wd
->大小写值{
EXIFEXT arg1_a1We
->对象[(T.pack“ExifText”。=toJSON arg1_a1We)]
出口arg1\u a1Wf
->对象[(T.pack“ExifInt”。=toJSON arg1\u a1Wf)]
ExifDouble arg1_a1Wg
->对象[(T.pack“ExifDouble”。=toJSON arg1_a1Wg)]
ExifBool arg1_a1Wh
->对象[(T.pack“ExifBool”。=toJSON arg1_a1Wh)]
ExifArray arg1_a1Wi
->对象[(T.pack“ExifArray”。=toJSON arg1_a1Wi)]}
来自JSON ExifValue的实例,其中
{parseJSON
=\value\u a1Wj
->的案例值_a1Wj{
对象对象对象
->case Data.Map.toList obj_一周{
[(conKey_a1Wl,conVal_a1Wm)]
->案例conKey_a1Wl{
_|(conKey_a1Wl==T.pack“ExifText”)
->1例心脏病患者{
arg_a1Wn
->(ExifText Data.Functor.parseJSON arg_a1Wn)}
|(conKey_a1Wl==T.pack“ExifInt”)
->1例心脏病患者{
arg_a1Wo
->(ExifInt Data.Functor.parseJSON arg_a1Wo)}
|(conKey_a1Wl==T.pack“ExifDouble”)
->1例心脏病患者{
arg_a1Wp
->(ExifDouble Data.Functor.parseJSON arg_a1Wp)}
|(conKey_a1Wl==T.pack“ExifBool”)
->1例心脏病患者{
arg_a1Wq
->(ExifBool Data.Functor.parseJSON arg_a1Wq)}
|(conKey_a1Wl==T.pack“ExifArray”)
->1例心脏病患者{
arg_a1Wr
->(ExifArray Data.Functor.parseJSON arg_a1Wr)}
|否则->Control.Monad.mzero}
_->Control.Monad.mzero}
_->Control.Monad.mzero}
instance ToJSON Exif where
  { toJSON
      = \ value_a1Va
          -> case value_a1Va of { Exif arg1_a1Vb -> toJSON arg1_a1Vb } }
instance FromJSON Exif where
  { parseJSON
      = \ value_a1Vc
          -> case value_a1Vc of {
               arg_a1Vd -> (Exif Data.Functor.<$> parseJSON arg_a1Vd) } }

instance ToJSON ExifValue where
  { toJSON
      = \ value_a1Wd
          -> case value_a1Wd of {
               ExifText arg1_a1We
                 -> object [(T.pack "ExifText" .= toJSON arg1_a1We)]
               ExifInt arg1_a1Wf
                 -> object [(T.pack "ExifInt" .= toJSON arg1_a1Wf)]
               ExifDouble arg1_a1Wg
                 -> object [(T.pack "ExifDouble" .= toJSON arg1_a1Wg)]
               ExifBool arg1_a1Wh
                 -> object [(T.pack "ExifBool" .= toJSON arg1_a1Wh)]
               ExifArray arg1_a1Wi
                 -> object [(T.pack "ExifArray" .= toJSON arg1_a1Wi)] } }
instance FromJSON ExifValue where
  { parseJSON
      = \ value_a1Wj
          -> case value_a1Wj of {
               Object obj_a1Wk
                 -> case Data.Map.toList obj_a1Wk of {
                      [(conKey_a1Wl, conVal_a1Wm)]
                        -> case conKey_a1Wl of {
                             _ | (conKey_a1Wl == T.pack "ExifText")
                               -> case conVal_a1Wm of {
                                    arg_a1Wn
                                      -> (ExifText Data.Functor.<$> parseJSON arg_a1Wn) }
                               | (conKey_a1Wl == T.pack "ExifInt")
                               -> case conVal_a1Wm of {
                                    arg_a1Wo
                                      -> (ExifInt Data.Functor.<$> parseJSON arg_a1Wo) }
                               | (conKey_a1Wl == T.pack "ExifDouble")
                               -> case conVal_a1Wm of {
                                    arg_a1Wp
                                      -> (ExifDouble Data.Functor.<$> parseJSON arg_a1Wp) }
                               | (conKey_a1Wl == T.pack "ExifBool")
                               -> case conVal_a1Wm of {
                                    arg_a1Wq
                                      -> (ExifBool Data.Functor.<$> parseJSON arg_a1Wq) }
                               | (conKey_a1Wl == T.pack "ExifArray")
                               -> case conVal_a1Wm of {
                                    arg_a1Wr
                                      -> (ExifArray Data.Functor.<$> parseJSON arg_a1Wr) }
                               | otherwise -> Control.Monad.mzero }
                      _ -> Control.Monad.mzero }
               _ -> Control.Monad.mzero } }