Haskell 在同一函数中混合Esqueleto和Persistent

Haskell 在同一函数中混合Esqueleto和Persistent,haskell,esqueleto,haskell-persistent,Haskell,Esqueleto,Haskell Persistent,我可能在做一些非常愚蠢的事情,但我想在同一个函数中混合一些Esqueleto和常规的持久性查询 我有以下职能: handleFactionConstruction :: (BaseBackend backend ~ SqlBackend, PersistStoreWrite backend, PersistQueryRead backend, PersistUniqueRead backend, MonadIO m) => Time -> Entity Fa

我可能在做一些非常愚蠢的事情,但我想在同一个函数中混合一些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 ()
这不起作用,我得到以下错误:

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 ()
我认为这与“后端兼容的SqlBackend”和“BaseBackend~SqlBackend”之间的区别有关

有没有办法让它工作起来?在这种情况下,我可以使用Esqueleto编写selectList部分,但接下来需要使用replace,这是Esqueleto不支持的(我想)


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

您可以将
后端兼容的SqlBackend
添加到
HandleActionConstruction
的约束列表中,以获得:

handleFactionConstruction :: (BaseBackend backend ~ SqlBackend,
    BackendCompatible SqlBackend backend
    PersistStoreWrite backend, PersistQueryRead backend, 
    PersistUniqueRead backend, MonadIO m) =>
    Time -> Entity Faction -> ReaderT backend m ()
更一般地说,
无法推断出
错误意味着您的类型签名比它允许的函数之一更通用。有三种方法可以处理此问题:

  • 添加约束,使类型签名更具体(如上所述)
  • 使您调用的函数(
    loadPlanetConstructionQueue
    )更通用
  • 如果上述两种方法都不可行,请以其他方式重写代码
handleFactionConstruction :: (BaseBackend backend ~ SqlBackend,
    BackendCompatible SqlBackend backend
    PersistStoreWrite backend, PersistQueryRead backend, 
    PersistUniqueRead backend, MonadIO m) =>
    Time -> Entity Faction -> ReaderT backend m ()