Question

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!

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top