如何使用aeson将数组解析为元组?

时间:2017-03-09 23:06:32

标签: json haskell serialization aeson

如果我有一个数组["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)

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

1 个答案:

答案 0 :(得分:1)

我会继续将数组解析为元组(String,Task),然后使用简单模式匹配,如果使用OverloadedStrings,可能需要指定“addTask”的类型,这可能是使用ScopedTypeVariables完成(只需将其添加到.. :: (String, Task) <- 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 -> Change在元组的第一个元素上总是case