Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell-JSON队列_Haskell - Fatal编程技术网

Haskell-JSON队列

Haskell-JSON队列,haskell,Haskell,我想在Haskell方面得到一些帮助,我对该语言和函数式编程非常陌生(曾在JavaScript中接触过它,但不太熟悉) 我需要解析由参数定义的不同类型的JSON对象,并首先存储它们以供以后处理,例如: [ { "new_agent": { "id": "8ab86c18-3fae-4804-bfd9-c3d6e8f66260", "name": "BoJack Horseman", "primary_skillset": ["bills-quest

我想在Haskell方面得到一些帮助,我对该语言和函数式编程非常陌生(曾在JavaScript中接触过它,但不太熟悉)

我需要解析由参数定义的不同类型的JSON对象,并首先存储它们以供以后处理,例如:

[
  {
    "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,并将其保留在数组中


下面的代码应该能让你找到做你想做的事情的大部分方法。它使用了与用户2407038建议的类似的技术。这三种不同的数据类型被收集到一个sum类型中:
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