列表中的每个元素都会触发一些数据库更新,但我一直遇到返回类型。能告诉我这是怎么回事?
for :: [a] -> (a -> b) -> [b]
for xs f = map f xs
-- Summary: Loop over the elements of xs and update the table for each element
-- get an ID from the element
-- get the record corresponding to that ID
-- extract more values
-- update table (below is just a dummy updateWhere
-- but the above values will be used in the update eventually )
forM_ xs $ \(Entity xid val) -> do
let qid = tableField val
y <- runDB $ get404 qid
let z = table2Field y
return $ updateWhere [PersonName ==. "Test"] [PersonAge *=. 1]
我收到以下错误:
Couldn't match type `PersistMonadBackend m0'
with `persistent-1.2.1:Database.Persist.Sql.Types.SqlBackend'
Expected type: PersistMonadBackend m0
Actual type: PersistEntityBackend Person
In the second argument of `($)', namely
`updateWhere [PersonName ==. name] [PersonAge *=. 1]'
我尝试使用 for
代替 forM or forM_
,但它没有修复任何问题。在这一点上,我只是尝试了一大堆组合而没有真正理解如何修复此错误。感谢您的帮助!
更新:
以下是我正在使用的实际代码。当我摆脱大多数let语句并只是通过一个简单的更新运行updateWhere时它仍然给我同样的错误。
getCalculateDeltaR :: personId -> Handler Html
getCalculateDeltaR personId = do
goods <- runDB $ selectList [GoodPerson ==. personId] []
forM goods $ \(Entity gid good) -> do
let aid = goodAsset good
asset <- runDB $ get404 aid
let mktValue = assetMktValue asset
return $ updateWhere [GoodPerson ==. personId, GoodAsset = aid] [GoodDelta =. (mktValue - GoodOrigValue)]
defaultLayout $ do
$(widgetFile "calculateDelta")
如果我将上面的forM更改为:
forM goods $ \(Entity gid good) -> do
return $ updateWhere [GoodPerson ==. personId] [GoodDelta =. 1]
我仍然会收到有关不匹配类型的相同错误。
答案 0 :(得分:1)
我对yesod不是很熟悉,但我认为以下代码应该有效:
forM_ xs $ \(Entity xid val) -> do
let qid = tableField val
y <- runDB $ get404 qid
let z = table2Field y
runDB $ updateWhere [PersonName ==. "Test"] [PersonAge *=. 1]
您不希望返回数据库操作然后将它们丢弃(forM_会抛出单个返回值),因为这只会导致无法执行操作。你必须运行它们。