【问题标题】:Mixing Esqueleto and Persistent in same function在同一功能中混合 Esqueleto 和 Persistent
【发布时间】:2018-10-05 03:22:03
【问题描述】:

我可能会做一些非常愚蠢的事情,但我想在同一个函数中将一些 Esqueleto 与常规持久查询混合使用。

我有功能:

handleFactionConstruction :: (BaseBackend backend ~ SqlBackend,
    PersistStoreWrite backend, PersistQueryRead backend, 
    PersistUniqueRead backend, MonadIO m) =>
    Time -> Entity Faction -> ReaderT backend m ()
handleFactionConstruction date faction = do
    planets <- selectList [ PlanetOwnerId ==. Just (entityKey faction)] []
    queues <- mapM loadPlanetConstructionQueue $ map entityKey planets
    return ()

并且 loadPlanetConstructionQueue 有签名(这个执行连接,因此我想在这里使用 Esqueleto):

loadPlanetConstructionQueue :: (MonadIO m, BackendCompatible SqlBackend backend, 
    PersistQueryRead backend, PersistUniqueRead backend) =>
    Key Planet -> ReaderT backend m (Maybe (Entity Planet), [Entity BuildingConstruction

这不起作用,我收到以下错误:

Could not deduce (BackendCompatible SqlBackend backend)
    arising from a use of ‘loadPlanetConstructionQueue’
  from the context: (BaseBackend backend ~ SqlBackend,
                     PersistStoreWrite backend, PersistQueryRead backend,
                     PersistUniqueRead backend, MonadIO m)
    bound by the type signature for:
               handleFactionConstruction :: forall backend (m :: * -> *).
                                            (BaseBackend backend ~ SqlBackend,
                                             PersistStoreWrite backend,
                                             PersistQueryRead backend,
                                             PersistUniqueRead backend, MonadIO m) =>
                                            Time -> Entity Faction -> ReaderT backend m ()

我认为这与“BackendCompatible SqlBackend backend”和“BaseBackend backend ~ SqlBackend”之间的区别有关。

有没有办法让这个工作?在这种情况下,我可以使用 Esqueleto 编写 selectList 部分,但更进一步,将需要使用 replace,Esqueleto 不支持(我认为)。

我对 Haskell、Persistent 或 Esqueleto 了解不多,所以我在这里有点迷茫。

【问题讨论】:

    标签: haskell esqueleto haskell-persistent


    【解决方案1】:

    可以将BackendCompatible SqlBackend backend添加到handleFactionConstruction的约束列表中,得到:

    handleFactionConstruction :: (BaseBackend backend ~ SqlBackend,
        BackendCompatible SqlBackend backend
        PersistStoreWrite backend, PersistQueryRead backend, 
        PersistUniqueRead backend, MonadIO m) =>
        Time -> Entity Faction -> ReaderT backend m ()
    

    更一般地说,Could not deduce 错误意味着您的类型签名比它允许的功能之一更通用。有三种方法可以处理:

    • 添加约束,使类型签名更具体(如上)
    • 使您调用的函数 (loadPlanetConstructionQueue) 更通用
    • 如果以上都不可行,请用其他方式重写代码

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-29
      • 1970-01-01
      • 2014-10-10
      • 2014-08-25
      • 2011-10-27
      • 1970-01-01
      • 2021-12-14
      相关资源
      最近更新 更多