2017-01-21 8 views
0

高レベルでServantに変換する一連の例外を使用してAPIハンドラーを実行できるようにするには、enter関数を使用しようとしていますが、型の一致に問題があります。Servantライブラリから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の実際の型は何ですか(何GHCiのは、私を与えるが、より記述的な説明になるではない):
    enter runApp :: ServerT Routes (ExceptT AppErr IO a) -> ServerT Routes (ExceptT ServantErr IO a) 
    

    ので、質問が多数ありますか?

  • その(IO ResponseReceived)制約はどこから来ていますか?
  • ハンドラ全体が自然な変換を通過するように、上記のコードを調整するにはどうすればよいですか?
+1

「ルート」はどのように見えますか?私はこれが新しいバージョンのサーバントで解決されたのかどうかはわかりませんが、ルートに 'Raw'エンドポイントを持つことはできませんでした。そうした場合、結果は奇妙なタイプのエラーになります。 – ondra

+0

これが正しい答えです!私はあなたに信用を与えることができるようにあなたの返信を答えにアップグレードできますか? –

答えて

4

RawエンドポイントをApiタイプにすることはできません。これを行う方法は、handlersからRawエンドポイントを取得して、それをたとえば

server c = enter runApp (handlers c) :<|> handleRaw 
関連する問題