如何解决如何让 GHC 将我的孤立实例“HasServer”和“HasClient”应用于“AuthProtect”?
我使用 servant: Servant.API.Experimental.Auth 中的 AuthProtect
组合子。那里没有太多代码,实例 HasServer (AuthProtect tag)
位于 servant-server
中,实例 HasClient (AuthProtect tag)
位于您使用的任何服务客户端中。
我使用 servant-snap
而不是 servant-server
以及一个 HasClient
项目的自定义 obelisk
实现,其项目结构由三个 cabal 包组成:
- 前端(由 ghcjs 编译)
- common(由 ghcjs 和 ghc 编译)
- 后端(由 ghc 编译)
我曾经有一个 AuthProtect
的自定义实现以及 common
包中的实例。但是,由于 ghcjs,common
既不能依赖于 servant-snap
,也不能依赖于 snap-core
。
现在我将 HasServer
实例移到后端......没问题,对吧?错误的。一旦 HasServer
实例被孤立,ghc 就不再正确解析我的 api 类型。就好像孤立的实例根本不存在一样。
这是为什么?
有什么,我能做什么?
解决方法
实例是全球性的...理论上。在实践中,为了支持单独编译,它们通过导入进行传播。因此,从使用它的模块导入定义实例的模块。以传递方式导入它就足够了 - 即导入一个模块,该模块导入一个模块,该模块导入定义实例的模块。
,其中任何一个都解决了我的问题:
instance HasServer api context m => HasServer (AuthProtect "jwt" :> api) context m where
type ServerT (AuthProtect "jwt" :> api) context m =
String -> ServerT api context m
hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy :: Proxy api) pc nt . s
route (Proxy :: Proxy (AuthProtect "jwt" :> api)) context subserver =
route (Proxy :: Proxy api) context (subserver `addAuthCheck` withRequest authCheck)
where
authCheck :: Request -> DelayedM m String
authCheck =
liftIO . evalSnap (pure "account info")
(\x -> pure $! (x `seq` ()))
(\f -> let !_ = f 0 in pure ())
如果我出于某种原因不想专门研究 AuthProtect "jwt"
,我必须提供约束 KnownSymbol tag
。
instance (KnownSymbol tag,HasServer api context m) => HasServer (AuthProtect tag :> api) context m where
type ServerT (AuthProtect tag :> api) context m =
String -> ServerT api context m
hoistServerWithContext _ pc nt s = hoistServerWithContext (Proxy :: Proxy api) pc nt . s
route (Proxy :: Proxy (AuthProtect tag :> api)) context subserver =
route (Proxy :: Proxy api) context (subserver `addAuthCheck` withRequest authCheck)
where
authCheck :: Request -> DelayedM m String
authCheck =
liftIO . evalSnap (pure "account info")
(\x -> pure $! (x `seq` ()))
(\f -> let !_ = f 0 in pure ())
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。