我有一个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
答案 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 ()
这个东西真的开始点击了!