我面临的问题非常简单:基本上我正在尝试计算Int和Double的乘积。在简单的Haskell中,我会运行
product = (fromIntegral int_val) * double_val
然而,我无法弄清楚如何在esqueleto中做到这一点。我有一个表B,它有一个Int类型的列“amount”和一个表C,它的列号为“Double”。当试图提取并计算产品时,像这样
(b ^. BAmount) *. (c ^. CPrice)
我收到类型错误(正如预期的那样):
Couldn't match type ‘Double’ with ‘Int’
Expected type: EntityField Drink Int
Actual type: EntityField Drink Double
我找不到帮助我的文档中的任何内容,实际上我根本不知道如何继续下去。 (有关更多代码,请参阅下面的完整示例。)
可能的解决方案:我当然可以将价格存储为Int,但我很感兴趣,如果可以用esqueleto来完成。
完整示例:
数据库:
表A:Id |名称
表B:Id | AId | BId |金额 其中Amount是Int,AId和BId是对表A和B的引用。
表C:Id |名称|价格, 这是Price a Double
我写的查询如下:
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)
修改:
我尝试过像这样使用fmap
和fromIntegral
:
let product = fmap fromIntegral (b ^. BAmount) *. (c ^. CPrice)
导致两个错误:
No instance for (Functor SqlExpr)
和
No instance for (Num (Value Double))
正如评论中所提到的(@Thomas M. DuBuisson),我试过:
let product = fmap (fmap fromIntegral) (b ^. BAmount) *. (c ^. CPrice)
解决了第二个问题,但我仍然得到No instance for (Functor SqlExpr)
。
编辑2 :
我在Yesod邮件列表上询问过这个问题。讨论可以在here找到。
答案 0 :(得分:1)
我不是专家,但您可能会尝试将<div data-ng-bind-html="documentDetail.Content | unsafe"></div>
应用于整数参数:
_floor
这可能会将您的整数变为双精度,因为floor_ :: (..., PersistField a, Num a, PersistField b, Num b)
=> expr (Value a) -> expr (Value b)
和a
可能不同。通常你用它来将双打变为整数,但它也可能反过来。
一些类似的Esqueleto函数也可以正常工作。
是的,这是一个黑客攻击。我希望有些专家可以提出更好的解决方案。
答案 1 :(得分:0)