为了缩短,我的代码是使用aeson解析json文件
这是我的两段代码:
a.hs
{-# LANGUAGE OverloadedStrings #-}
import Data.Aeson
import qualified Data.ByteString.Lazy.Char8 as C
import Control.Monad
import Control.Applicative
data AuctionInfo = AuctionInfo {
realm :: Realm ,
alliance :: Auctions ,
horde :: Auctions ,
neutral :: Auctions
} deriving (Show )
instance FromJSON AuctionInfo where
parseJSON (Object o) = do
r <- o .: "realm" >>= parseJSON
a <- o .: "alliance" >>= parseJSON
h <- o .: "horde" >>= parseJSON
n <- o .: "neutral" >>= parseJSON
return $ AuctionInfo r a h n
parseJSON _ = mzero
data Realm = Realm { name2 :: String , slug:: String} deriving (Show )
instance FromJSON Realm where
parseJSON (Object o) = Realm <$>
o .: "name" <*>
o .: "slug"
parseJSON _ = mzero
data Auctions = Auctions {auctions :: [Auc]} deriving (Show)
instance FromJSON Auctions where
parseJSON (Object o ) = Auctions <$> o.: "auctions"
parseJSON _ = mzero
data Auc = Auc {
auc :: Integer,
itme :: Int,
owner :: String,
bid :: Integer,
buyout ::Integer,
quantity :: Int,
timeLeft :: String,
rand :: Integer,
seed :: Integer
} deriving (Show )
instance FromJSON Auc where
parseJSON (Object o ) = Auc <$>
o .: "auc" <*>
o .: "item" <*>
o .: "owner" <*>
o .: "bid" <*>
o .: "buyout" <*>
o .: "quantity" <*>
o .: "timeLeft" <*>
o .: "rand" <*>
o .: "seed"
parseJSON _ = mzero
main = do
au<- C.readFile "a.json"
let x = decode au :: Maybe AuctionInfo
case x of
Just a -> do
{-putStrLn.show $ a-}
putStrLn .show.length.auctions.alliance $ a
putStrLn "ok"
Nothing -> putStrLn "fail"
测试步骤:
aeson
,$ cabal install aseon
$ ghc a.hs -o a
$ ./a
我从输出中获得的是“失败”。
当我运行命令$ runghc a.hs
几次时,
我甚至将一些ok
和一些fail
混合在一起。
我也在我的linux和64bit mac ghc上尝试了这个代码,它们都按照我的预期输出ok
。
我的一位朋友也在他的32位mac ghc fail
上尝试了这段代码。他告诉我,他为我的代码扮演了一些黑魔法并将一行更改为
let x = decode $(C.pack. C.unpack) au :: Maybe AuctionInfo
然后输出为ok
。但是当我做同样的黑魔术时,输出仍然是fail
。
我只是想确定这是我的错误还是ghc的错误,或者我该如何确定。
答案 0 :(得分:2)
我不确定该行为是否与此相关,但您绝对不应该使用Data.ByteString.Lazy.Char8
,因为这仅适用于8位ASCII数据且输入为UTF-8。
尝试用
替换该导入import qualified Data.ByteString.Lazy as BL
并使用BL.readFile
读取数据(当然实际名称无关紧要,但BL
是lazy bytestring包的惯用简写。)
请注意,通常您会使用Data.Text
来处理unicode文本,但在这种情况下,aeson
API需要二进制(即ByteString
)表示并处理内部解码unicode。 / p>
编辑:实际上现在我已经考虑过这个问题了,我认为问题不在于使用Char8
(尽管关于通常不会将它用于unicode文本)您没有从String
或Char
进行任何转换(期待C.pack . C.unpack
实验,这会破坏所有多字节字符。)