如何获得yesod-persistent来识别我的aeson解析实体数组的类型?

时间:2014-07-11 00:32:35

标签: haskell yesod persistent aeson

我有一个yesod处理程序,可以接受一些带有对象数组的json。 我想将所有对象插入数据库。

newtype NodeList = NodeList [Node]

instance FromJSON NodeList where
    parseJSON (Object o) = NodeList <$> o .: "nodes"
    parseJSON _ = mzero

postMoreNodesR :: Handler ()
postMoreNodesR = do
        nodes::NodeList <- requireJsonBody
        runDB $ mapM_ insert nodes
        return ()

但有些如何,它不承认我的实体类型。 (虽然同一模块中的其他POST和GET处理程序工作得很好。)我可以说我非常接近,但我不知道该怎么做,因为“a0”不是我在任何地方声明的类型。这是错误:

Handler/Node.hs:46:30:
    Couldn't match expected type `[a0]' with actual type `NodeList'
    In the second argument of `mapM_', namely `nodes'
    In the second argument of `($)', namely `mapM_ insert nodes'
    In a stmt of a 'do' block: runDB $ mapM_ insert nodes

2 个答案:

答案 0 :(得分:3)

您还可以直接在绑定中进行模式匹配:

postMoreNodesR :: Handler ()
postMoreNodesR = do
  NodeList nodes <- requireJsonBody

  runDB $ mapM_ insert nodes

  return ()

这也消除了对类型注释的需要。

这是有效的,因为do表达式对于lambda:

是脱糖的
requireJsonBody >>= \NodeList nodes -> runDB -- ...

答案 1 :(得分:1)

我明白了!我遵循了类型并意识到我需要一个辅助函数来从newtyped NodeList中提取节点:

getNodesFromList :: NodeList -> [Node]
getNodesFromList (NodeList l) = l

然后我的处理函数变为:

postMoreNodesR :: Handler ()
postMoreNodesR = do
        nodes::NodeList <- requireJsonBody
        runDB $ mapM_ insert $ getNodesFromList nodes
        return ()

这个东西真的开始点击了!