在同一个函数中混合 Esqueleto 和 Persistent
Mixing Esqueleto and Persistent in same function
我可能在做一些非常愚蠢的事情,但我想在同一个函数中混合一些 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 部分,但进一步向下将需要使用替换,Esqueleto 不支持(我认为)。
我对 Haskell、Persistent 或 Esqueleto 了解不多,所以我在这里有点迷路。
您可以将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
) 更通用
- 如果以上都不可能,请用其他方式重写代码
我可能在做一些非常愚蠢的事情,但我想在同一个函数中混合一些 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 部分,但进一步向下将需要使用替换,Esqueleto 不支持(我认为)。
我对 Haskell、Persistent 或 Esqueleto 了解不多,所以我在这里有点迷路。
您可以将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
) 更通用 - 如果以上都不可能,请用其他方式重写代码