我是一个初学者,试图通过解析一些我在网上找到的json文件来了解有关Haskell和Aeson的更多信息。
我有一个.json
,看起来像这样
"Abilities": {
"Prime": {
"Ammo": 210,
"Available": true,
"Diposition": 3,
"Type": "Secondary",
"Class": "Pistols",
"NormalAttack": {
"Chance": 0.25,
"Streak": 2,
"Rate": 2.67,
"ShotType": "Hit-Scan",
"Damage": {
"Front": 15,
"Back": 15,
"Up": 120,
"Down": 40
},
"Status": 0.25
}
"Accuracy": 9.8,
"Reload": 3,
"Name": "Prime",
"Magazine": 16,
},
"Dual": {
"Name": "Dual",
"Available": true,
"Diposition": 4,
"Class": "Swords",
"Type": "Melee",
"NormalAttack": {
"Chance": 0.25,
"Streak": 3,
"Rate": 1.08,
"Damage": {
"Down": 35
},
"Status": 0.15
}
}
}
该文件包含一些我需要的信息,但是大多数不需要的信息。
这是我到目前为止尝试过的
{-# LANGUAGE DeriveGeneric #-}
module Lib
( someFunc
) where
import Data.Aeson
import Data.HashMap.Strict as HS
import Data.Maybe
import Data.Text
import Data.Map.Strict
import GHC.Generics
location = "src/this.json"
someFunc :: IO ()
someFunc = putStrLn "someFunc"
data Abilities = Abilities { abilities :: Map String Ability } deriving (Generic, Show)
instance FromJSON Abilities where
parseJSON = withObject "Abilities" $
\v -> Abilities
<$> v .: pack "Abilities"
data Ability = Ability { ammo :: Double
, normalAttack :: Effect
, accuracy :: Double
, name :: String
, diposition :: Double
, reload :: Double
} deriving (Generic, Show)
instance FromJSON Ability where
parseJSON = withObject "Ability" $
\v -> Ability
<$> v .: pack "Ammo"
<*> v .: pack "NormalAttack"
<*> v .: pack "Accuracy"
<*> v .: pack "Name"
<*> v .: pack "Diposition"
<*> v .: pack "Reload"
data Effect = Effect { chance :: Double
, streak :: Double
, rate :: Double
, damage :: Damage
, status :: Double
} deriving (Generic, Show)
instance FromJSON Effect where
parseJSON = withObject "Effect" $
\v -> Effect
<$> v .: pack "Chance"
<*> v .: pack "Streak"
<*> v .: pack "Rate"
<*> v .: pack "Damage"
<*> v .: pack "Status"
data Damage = Damage { front :: Double
, back :: Double
, up :: Double
, down :: Double
} deriving (Generic, Show)
instance FromJSON Damage where
parseJSON = withObject "Damage" $
\v -> Damage
<$> v .: pack "Front"
<*> v .: pack "Back"
<*> v .: pack "Up"
<*> v .: pack "Down"
main = do
x <- eitherDecodeFileStrict location :: IO (Either String Abilities)
print x
我知道几种解析信息的方式
通过分析文件具有Aeson Value
或Aeson Object
并应用Data.HashMap.Strict.toList
将其转换为[(k, v)]
。麻烦的是,在大文件上,此方法会变得非常混乱。
使用几个像这样工作的unConstructor
函数
unConstruct (Constructor x) = case (Constructor x) of
Constructor x -> x
但是同样的问题:它变得非常难以理解,而且混乱得很快。
这就是为什么我要解析上面的代码中所示的.json
文件。
但是由于我得到Nothing
作为输出,所以解析在代码中的某个地方失败了。
.json
文件似乎不错,因为如果我使用
main = do
x <- decodeFileStrict location :: IO (Maybe Object)
print x
它工作正常,可以使用适当的默认aeson数据类型打印文件的内容。
我可能做错了什么?
编辑:已实施@danidiaz在评论中建议的修复程序。
错误消息:Left "Error in $.Abilities['someAbility']: key \"Ammo\" not present"