Haskell-JSON队列
我想在Haskell方面得到一些帮助,我对该语言和函数式编程非常陌生(曾在JavaScript中接触过它,但不太熟悉) 我需要解析由参数定义的不同类型的JSON对象,并首先存储它们以供以后处理,例如:Haskell-JSON队列,haskell,Haskell,我想在Haskell方面得到一些帮助,我对该语言和函数式编程非常陌生(曾在JavaScript中接触过它,但不太熟悉) 我需要解析由参数定义的不同类型的JSON对象,并首先存储它们以供以后处理,例如: [ { "new_agent": { "id": "8ab86c18-3fae-4804-bfd9-c3d6e8f66260", "name": "BoJack Horseman", "primary_skillset": ["bills-quest
[
{
"new_agent": {
"id": "8ab86c18-3fae-4804-bfd9-c3d6e8f66260",
"name": "BoJack Horseman",
"primary_skillset": ["bills-questions"],
"secondary_skillset": []
}
},
{
"new_job": {
"id": "f26e890b-df8e-422e-a39c-7762aa0bac36",
"tipo": "rewards-question",
"urgent": false
}
},
{
"job_request": {
"agent_id": "ed0e23ef-6c2b-430c-9b90-cd4f1ff74c88"
}
}
]
这意味着我需要存储3种不同类型的阵列,它们将来必须相互交互
到目前为止,通过教程,我已经找到了足够多的指导,让我找到了这个简单的代码,可以用fromJSON和toJSON打印一个对象,我可以复制到其他对象,但在决定如何解析它之前,我仍然不知道如何通过第一个参数(new_代理、new_作业、job_请求)获取对象:
{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}
import Data.Aeson
import Data.Text
import Control.Applicative
import Control.Monad
import qualified Data.ByteString.Lazy as B
import GHC.Generics
data Agent =
Agent { agentId :: Text
, name :: Text
, primary_skillset :: [Text]
, secondary_skillset :: [Text]
} deriving Show
instance FromJSON Agent where
parseJSON (Object v) =
Agent <$> v .: "id"
<*> v .: "name"
<*> v .: "primary_skillset"
<*> v .: "secondary_skillset"
parseJSON _ = mzero
instance ToJSON Agent where
toJSON (Agent agentId name primary_skillset secondary_skillset) =
object [ "id" .= agentId
, "name" .= name
, "primary_skillset" .= primary_skillset
, "secondary_skillset" .= secondary_skillset
]
jsonFile :: FilePath
jsonFile = "sample-input.json"
-- Read the local copy of the JSON file.
getJSON :: IO B.ByteString
getJSON = B.readFile jsonFile
main :: IO ()
main = do
-- Get JSON data and decode it
d <- (eitherDecode <$> getJSON) :: IO (Either String [Agent])
-- If d is Left, the JSON was malformed.
-- In that case, we report the error.
-- Otherwise, we perform the operation of
-- our choice. In this case, just print it.
case d of
Left err -> putStrLn err
Right ps -> print ps
{-#语言重载字符串,DeriveGeneric}
导入数据.Aeson
导入数据.Text
导入控制
进口管制
将限定数据.ByteString.Lazy作为B导入
进口GHC.仿制药
数据代理=
代理{agentId::Text
,name::Text
,主要技能集::[文本]
,次要技能集::[文本]
}衍生节目
实例FromJSON代理,其中
parseJSON(对象v)=
代理v.:“id”
v.:“姓名”
v.:“主要技能集”
v.:“二级技能集”
parseJSON=mzero
实例ToJSON代理,其中
toJSON(代理agentId名称主技能集辅助技能集)=
对象[“id”。=agentId
,“名称”。=名称
,“主要技能集”。=主要技能集
,“次要技能集”。=次要技能集
]
jsonFile::FilePath
jsonFile=“sample input.json”
--读取JSON文件的本地副本。
getJSON::IO B.ByteString
getJSON=B.readFile jsonFile
main::IO()
main=do
--获取JSON数据并对其进行解码
d putStrLn错误
右ps->打印ps
我正在寻找以下问题的答案(如果可能,请使用代码片段):
- 如何通过id获取对象中的对象,然后将其添加到数组中
- 将对象存储在数组中后,每当需要再次使用某个特定信息时,如何对其进行“迭代”(按对象键搜索)
- 如何在数组中分配(更新)JSON,并将其保留在数组中
SomeObj
。为SomeObj
类型创建了三个不同的解析器,第一个成功的解析器是已使用的解析器,其他两个未使用
如果可能,我会让编译器自动定义JSON功能
我添加了额外的代码,通过转换回JSON,然后解码JSON来验证结果
需要“DuplicateRecordFields
”语言扩展,以便Agent
和Job
都可以有一个id
字段
解析JSON后,您应该能够使用List
功能执行您描述的搜索和更新操作
{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}
{-# LANGUAGE DuplicateRecordFields #-}
import Data.Aeson
import Data.Text
import Control.Applicative
import Control.Monad
import qualified Data.ByteString.Lazy as B
import GHC.Generics
data Agent =
Agent { id :: Text
, name :: Text
, primary_skillset :: [Text]
, secondary_skillset :: [Text]
} deriving (Show, Generic)
instance FromJSON Agent
instance ToJSON Agent
data Job =
Job { id :: Text
, tipo :: Text
, urgent :: Bool
} deriving (Show, Generic)
instance FromJSON Job
instance ToJSON Job
newtype JobRequest =
JobRequest { agent_id :: Text
} deriving (Show, Generic)
instance FromJSON JobRequest
instance ToJSON JobRequest
data SomeObj =
AnAgent Agent
| AJob Job
| AJobRequest JobRequest
deriving (Show, Generic)
newAgentTag = "new_agent"
newJobTag = "new_job"
jobRequestTag = "job_request"
instance FromJSON SomeObj where
parseJSON (Object v) =
let -- create multiple parsers.
parseAgent = AnAgent <$> (v .: newAgentTag)
parseJob = AJob <$> (v .: newJobTag)
parseJobRequest = AJobRequest <$> (v .: jobRequestTag)
in -- Use one of the collection of parsers.
parseAgent <|> parseJob <|> parseJobRequest
parseJSON _ = mzero
instance ToJSON SomeObj where
toJSON (AnAgent agent) = object [newAgentTag .= agent]
toJSON (AJob job) = object [newJobTag .= job]
toJSON (AJobRequest jobRequest) = object [jobRequestTag .= jobRequest]
jsonFile :: FilePath
jsonFile = "sample-input.json"
-- Read the local copy of the JSON file.
getJSON :: IO B.ByteString
getJSON = B.readFile jsonFile
main :: IO ()
main = do
-- Get JSON data and decode it
d <- (eitherDecode <$> getJSON) :: IO (Either String [SomeObj])
-- If d is Left, the JSON was malformed.
-- In that case, we report the error.
-- Otherwise, we perform the operation of
-- our choice. In this case, just print it.
case d of
Left err -> putStrLn err
Right ps -> do
print ps
-- convert back to JSON.
let j2 = encode ps --
print j2
-- decode the newly converted JSON
let d2 = eitherDecode j2 :: Either String [SomeObj]
case d2 of
Left err -> putStrLn err
Right ps2 -> do
print ps2
{-#语言重载字符串,DeriveGeneric}
{-#语言重复记录字段#-}
导入数据.Aeson
导入数据.Text
导入控制
进口管制
将限定数据.ByteString.Lazy作为B导入
进口GHC.仿制药
数据代理=
代理{id::Text
,name::Text
,主要技能集::[文本]
,次要技能集::[文本]
}派生(显示,通用)
来自JSON代理的实例
实例ToJSON代理
数据作业=
作业{id::Text
,tipo::Text
紧急的,紧急的
}派生(显示,通用)
来自JSON作业的实例
实例到JSON作业
新类型作业请求=
作业请求{agent_id::Text
}派生(显示,通用)
实例FromJSON作业请求
实例ToJSON作业请求
数据对象j=
生长剂
|工作
|作业请求
派生(显示,通用)
newAgentTag=“新代理”
newJobTag=“新作业”
jobRequestTag=“作业请求”
来自JSON SomeObj的实例,其中
parseJSON(对象v)=
让我们创建多个解析器。
parseAgent=AnAgent(v.:newAgentTag)
parseJob=AJob(v.:newJobTag)
parseJobRequest=AJobRequest(v.:jobRequestTag)
in——使用解析器集合中的一个。
parseAgent parseJob parseJobRequest
parseJSON=mzero
实例ToJSON SomeObj,其中
toJSON(管理代理)=对象[newAgentTag.=agent]
toJSON(AJob作业)=对象[newJobTag.=job]
toJSON(AJobRequest jobRequest)=对象[jobRequestTag.=jobRequest]
jsonFile::FilePath
jsonFile=“sample input.json”
--读取JSON文件的本地副本。
getJSON::IO B.ByteString
getJSON=B.readFile jsonFile
main::IO()
main=do
--获取JSON数据并对其进行解码
d putStrLn错误
右ps->do
打印ps
--转换回JSON。
设j2=编码ps--
打印j2
--解码新转换的JSON
让d2=eitherDecode j2::任意字符串[SomeObj]
案件d2
左错误->右错误
右ps2->do
打印ps2
通过检查给定的值
是否为对象,然后检查该对象的哈希映射是否只有一个字段,为每个不同的对象类型(例如数据SomeObj=managent Agent | AJob Job | AJobRequest JobRequest
)定义一个带有一个变量的求和类型,其键是变体的三个键之一,然后递归解析对应于该键的值。伊森本身是如何做到的;唯一的区别是与键匹配的值。非常感谢!这已经帮了我很多忙了。虽然我遇到了一个场景,它似乎没有解析I