【问题标题】:How to parse array into tuple with aeson?如何使用 aeson 将数组解析为元组?
【发布时间】:2017-03-09 23:06:32
【问题描述】:

如果我有一个数组["addTask", {"id": "1", "description": "d", "dependsOn": [], "dependentTasks": []}]

data Task = Task
    { id :: String
    , description :: String
    , dependsOn :: [String]
    , dependentTasks :: [String]
    } deriving (Eq, Show, Generic, ToJSON, FromJSON)
type Change = Storage -> Storage
addTask :: Task -> Change
addTask (Task id desc dep dept) = insert id (Task id desc dep dept)

我怎样才能创建一个解析器来生成一个 addTask 呢?

instance FromJSON (Storage -> Storage) where
    parseJSON (Array v) = do
        name <- parseJSON $ v V.! 0 :: Just String
        task <- parseJSON $ v V.! 1 :: Just Task
        return (addTask task)

这是我目前的尝试,但不起作用。

【问题讨论】:

  • 如果您的尝试不起作用 - 请描述您遇到的错误/行为与预期

标签: json haskell serialization aeson


【解决方案1】:

我会继续将数组解析为元组(String,Task),然后使用简单的模式匹配,如果您使用OverloadedStrings,您可能需要指定“addTask”的类型,这可以使用@987654323 来完成@(只需将其添加到.. :: (String, Task) &lt;- parse.. 的左侧)。

instance FromJSON (Storage -> Storage) where
    parseJSON v = do ("addTask",t) <- parseJSON v
                     return $ addTask t

注意:我没有编译或测试这段代码

编辑

使用替代非常简单,您只需定义两个解析器并将它们组合起来

instance FromJSON (Storage -> Storage) where
    parseJSON v = let addP = do ("addTask",t) <- parseJSON v
                                return $ addTask t
                      rmP = do ("rmTask",n) <- parseJSON v
                               return $ rmTask n
                   in addP <|> rmP

我假设 rmTask :: Int -&gt; Change 否则 cou 总是可以在元组的第一个元素上使用 case

【讨论】:

  • 这行得通,谢谢!我可能应该问另一个问题,但是,你能解释一下如何在这里使用 Alternative 吗?我的意思是如果字符串是"addTask" ,那么如果它失败则返回`addTask t`(例如它是["removeTask", "id"]尝试另一个解析器等。从教程中我可能可以定义一个Parser这样做,但是怎么做这个parseJSON - 我不确定。
  • @user1685095 更新
猜你喜欢
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-12
  • 2015-03-29
相关资源
最近更新 更多