I am trying to update a column of a table based on other columns but looks like I cannot do it with the updateWhere function. So I tried to use rawSQl but it does not work due to ambiguous type error.
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
runDB $ rawSql "UPDATE good SET delta = (? - orig_value) \
WHERE person = ? AND asset = ?"
[toPersistValue mktValue, toPersistValue personId, toPersistValue aid]
defaultLayout $ do
$(widgetFile "calculateDelta")
I get the following error and I did try adding ?? after UPDATE but it did not make a difference.
Ambiguous type variable `a0' in the constraint:
(RawSql a0) arising from a use of `rawSql'
Probable fix: add a type signature that fixes these type variable(s)
In the second argument of `($)', namely
`rawSql
...
...
The parameters that I can passing to rawSQL are well defined so not sure what's causing this issue. Could someone tell me how I should resolve the above issue? If there is a better way to update columns based on other columns, would love to know that as well.
Thanks!
I don't know persistent
well, but that type error occurs because you're combining functions in such a way that a value gets produced an consumed without being inspected. For instance, if you had functions f :: a -> (Int, c)
and g :: (Int, c) -> b
then g . f
feels like it ought to have the type a -> b
, but it's actually an error because GHC has no idea what c
should have been.
The way to solve it is to inspect that (Int, c)
value in such a way that c
can be resolved to a particular type. This is often done with manual type annotations or by using asTypeOf
.