この関数を使用して、高レベルで Servant に変換する 1 つの例外セットを使用して API ハンドラーを実行できるようにしようとしていenter
ますが、型の一致に問題があります。
この最小限の定義セットを考えると、次のようになります。
-- server :: Config -> Server Routes
server :: Config -> ServerT Routes (ExceptT ServantErr IO)
server c = enter runApp (handlers c)
-- runApp :: AppM :~> Handler
runApp :: ExceptT AppErr IO :~> ExceptT ServantErr IO
runApp = Nat undefined
handlers :: Config -> ServerT Routes (ExceptT AppErr IO)
handlers = undefined
私はこのタイプのエラーで終わります:
Couldn't match type `IO' with `ExceptT ServantErr IO'
arising from a functional dependency between:
constraint `servant-0.7.1:Servant.Utils.Enter.Enter
(IO ResponseReceived)
(ExceptT AppErr IO :~> ExceptT ServantErr IO)
(IO ResponseReceived)'
arising from a use of `enter'
instance `servant-0.7.1:Servant.Utils.Enter.Enter
(m a) (m :~> n) (n a)'
at <no location info>
In the expression: enter runApp (handlers c)
In an equation for `server': server c = enter runApp (handlers c)
例外は、への呼び出しのある行から発生しenter
ます。参考までに、次の宣言enter
:
class Enter typ arg ret | typ arg -> ret, typ ret -> arg where
enter :: arg -> typ -> ret
instance Enter (m a) (m :~> n) (n a) where
-- enter :: (m :~> n) -> m a -> n a
したがって、 を呼び出すとenter runApp
、型が次のようになると予想されます。
enter :: (m :~> n) -> m a -> n a
enter (runApp :: m ~ ExceptT AppErr IO :~> n ~ ExceptT ServantErr IO) :: ExceptT AppErr IO a -> ExceptT ServantErr IO a
(上記でn ~ ExceptT ServantErr IO
は、型の置換を説明するために使用していました)
そして実際には、私は他のコードから(私が模倣しようとしたが、どこが間違っていたのか理解していない)、次のenter runApp
タイプを持っているべき/持っている必要があることを知っています:
enter runApp :: ServerT Routes (ExceptT AppErr IO a) -> ServerT Routes (ExceptT ServantErr IO a)
したがって、質問は多数あります。
- 実際のタイプは
enter runApp
何ですか(ghciが私に与えるものではなく、より説明的な説明です)? - その(IO ResponseReceived)制約はどこから来ていますか?
- 上記のコードを微調整して、ハンドラー全体が自然な変換を通過するようにするにはどうすればよいですか?