Multiplying Int and double values ββin esqueleto?
The problem I am facing is quite simple: basically I am trying to compute the Int and Double product. In plain Haskell, I just ran
product = (fromIntegral int_val) * double_val
However, I cannot figure out how to do this in esqueleto. I have table B that has a "sum" column of type Int and table C which has a column "price" of type Double. When trying to fetch both and compute the product like
(b ^. BAmount) *. (c ^. CPrice)
I am getting an error like (as expected):
Couldn't match type βDoubleβ with βIntβ
Expected type: EntityField Drink Int
Actual type: EntityField Drink Double
I couldn't find anything in the docs that helped me and I don't know how to do this at all. (See full example below for details).
Possible solution: I could of course just store the price as Int, but I'm wondering if this can be done using esqueleto.
Complete example :
Database:
Table A: Id | Name
Table B: Id | AId | BId | Sum where Amount is Int, and AId and BId are references to tables A and B.
Table C: Id | Name | Price, here Price Double
The request I recorded looks like this:
result <- liftIO $ runDb $ select $
from $ \(a, b, c) -> do
where_ (a ^. AId ==. b ^. BAId)
where_ (b ^. BCId ==. c ^. CId)
let product = (b ^. BAmount) *. (c ^. CPrice)
let total = sum_ product :: SqlExpr (Value (Maybe Double))
groupBy $ a ^. AName
return (a ^. AName)
EDIT
I've tried using fmap
and fromIntegral
like this:
let product = fmap fromIntegral (b ^. BAmount) *. (c ^. CPrice)
which results in two errors:
No instance for (Functor SqlExpr)
and
No instance for (Num (Value Double))
As suggested in the comments (by @Thomas M. DuBuisson) I tried:
let product = fmap (fmap fromIntegral) (b ^. BAmount) *. (c ^. CPrice)
which solves the second problem, but I still get it No instance for (Functor SqlExpr)
.
EDIT 2 :
I asked about this on the Yesod mailing list. A discussion can be found here .
source to share
I'm not an expert, but you can try applying integer_floor
to your parameter :
floor_ :: (..., PersistField a, Num a, PersistField b, Num b)
=> expr (Value a) -> expr (Value b)
It can turn your whole in double, as a
and b
may be different. You usually use it to convert doubles to integers, but it can also work the other way around.
Some of Esqueleto's similar features may work as well.
And yes, it's a hack. Hope some expert can suggest a better solution.
source to share