如何让 yesod-persistent 识别我的 aeson 解析实体数组的类型?
Posted
技术标签:
【中文标题】如何让 yesod-persistent 识别我的 aeson 解析实体数组的类型?【英文标题】:how do I get yesod-persistent to recognize the type of my aeson parsed entity array? 【发布时间】:2014-07-11 00:32:35 【问题描述】:我有一个 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
【问题讨论】:
【参考方案1】:你也可以直接在绑定中进行模式匹配:
postMoreNodesR :: Handler ()
postMoreNodesR = do
NodeList nodes <- requireJsonBody
runDB $ mapM_ insert nodes
return ()
这也消除了对类型注释的需要。
它之所以有效,是因为 do 表达式被取消了对 lambda 的糖分:
requireJsonBody >>= \NodeList nodes -> runDB -- ...
【讨论】:
更好!我不知道你可以在 do 块内进行模式匹配。 它实际上并没有脱糖为 lambda。它比这更复杂,感谢fail
。【参考方案2】:
我想通了!我遵循了类型并意识到我需要一个辅助函数来从新类型的 NodeList 中提取节点:
getNodesFromList :: NodeList -> [Node]
getNodesFromList (NodeList l) = l
然后我的处理函数变成了:
postMoreNodesR :: Handler ()
postMoreNodesR = do
nodes::NodeList <- requireJsonBody
runDB $ mapM_ insert $ getNodesFromList nodes
return ()
这玩意儿真的开始点击了!
【讨论】:
实际上,Haskell 可以自动为您生成该函数:)data NodeList = NodeList getNodesFromList :: [Node]
以上是关于如何让 yesod-persistent 识别我的 aeson 解析实体数组的类型?的主要内容,如果未能解决你的问题,请参考以下文章