繁体   English   中英

在Esqueleto中获取聚合函数的结果

[英]Getting the result of aggregate functions in Esqueleto

说我有以下型号:

Person
    stackOverflowUser Bool
    age Int Maybe

使用Esqueleto(&Yesod),说我想获得Stack Overflow用户的平均年龄。 我想用类型签名创建一个函数:

userAge :: Handler (Maybe Int)

到目前为止,我有以下内容:

userAge :: Handler [Value (Maybe Int)]
userAge = runDB $
    select $
    from $ \person -> do
    where_ (person ^. PersonStackOverflowUser ==. val True)
    return joinV $ avg_ (person ^. PersonAge)

这让我[Value(Maybe Int)],但我需要深入到“Maybe Int”。 我试过了

mapM_ unValue userAge

但由于某种原因,这样做会引发类型错误,给我[Maybe()]而不是[Maybe Int] ...另外,我认为上面代码中的最后一行应该有:

person ?. PersonAge

而不是

person ^. PersonAge

因为PersonAge可以为NULL,但更改它会给我一个类型错误,因为:

avg_ :: (PersistField a, PersistField b) => expr (Value a) -> expr (Value (Maybe b))
(^.) :: (PersistEntity val, PersistField typ) => expr (Entity val) -> EntityField val typ -> expr (Value typ)
(?.) :: (PersistEntity val, PersistField typ) => expr (Maybe (Entity val)) -> EntityField val typ -> expr (Value (Maybe typ))

这可能比我想要的更容易,但我无法在网上找到任何在Esqueleto使用聚合函数的例子,而且我对Haskell很新,所以我很难搞清楚它。

我想我可以使用原始SQL,但如果有可能我想使用Esqueleto来做这件事。

得到它了! 终于把我的头围绕着类型错误并想出了这个:

import Safe (headMay)
import Control.Monad (join)
import Database.Esqueleto
-- other misc Yesod imports

userAge :: Handler (Maybe Int)
userAge = do
    a <- runDB $ select $
                 from $ \person -> do
                 where_ (person ^. PersonStackOverflowUser ==. val True)
                 return $ joinV $ avg_ (person ^. PersonAge)
    return $ join (headMay (map unValue a))

“人^。PersonAge”似乎没有引起任何问题; 我在null和非null值上测试了它。 我想是“?”。 运算符保留用于其他情况。

希望这可以节省别人一些时间搞清楚!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM