3

サーバントのチュートリアルに表示されているアプリを少し変更して、Readerモナドを aReaderTにしました。

{-# LANGUAGE DataKinds                  #-}
{-# LANGUAGE DeriveGeneric              #-}
{-# LANGUAGE FlexibleInstances          #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses      #-}
{-# LANGUAGE OverloadedStrings          #-}
{-# LANGUAGE PolyKinds                  #-}
{-# LANGUAGE ScopedTypeVariables        #-}
{-# LANGUAGE TupleSections              #-}
{-# LANGUAGE TypeOperators              #-}

module Lib
    ( runServer
    ) where

import           Control.Monad.Except
import           Control.Monad.Reader
import qualified Data.Text                as T
import           Network.Wai
import           Servant

type WebApi
  =    "static" :> Raw
  :<|> "foo" :> Get '[PlainText] T.Text

type Foo = String

server :: ServerT WebApi (ReaderT Foo (ExceptT ServantErr IO))
server = static :<|> foo
  where
    static :: Application
    static = undefined

    -- Handler T.Text
    foo :: ReaderT Foo (ExceptT ServantErr IO) T.Text
    foo = undefined

webAPI :: Proxy WebApi
webAPI = Proxy

readerToHandler :: Foo -> ReaderT Foo (ExceptT ServantErr IO) :~> ExceptT ServantErr IO
readerToHandler t = Nat (\x -> runReaderT x t)

-- readerServer :: ServerT WebApi (ExceptT ServantErr IO)
-- readerServer = enter (readerToHandler "foobarbaz") server

-- serve' :: Application
-- serve' = serve webAPI server

runServer :: IO ()
runServer = return ()

問題は、関数を有効にできないことreaderServerです。型チェックはこの不可解なエラーで失敗します

src/Lib.hs:45:16: error:
    • Couldn't match type ‘IO’ with ‘ExceptT ServantErr IO’
        arising from a functional dependency between:
          constraint ‘Servant.Utils.Enter.Enter
                        (IO ResponseReceived)
                        (ReaderT Foo (ExceptT ServantErr IO) :~> ExceptT ServantErr IO)
                        (IO ResponseReceived)’
            arising from a use of ‘enter’
          instance ‘Servant.Utils.Enter.Enter (m a) (m :~> n) (n a)’
            at <no location info>
    • In the expression: enter (readerToHandler "foobarbaz") server
      In an equation for ‘readerServer’:
          readerServer = enter (readerToHandler "foobarbaz") server
Failed, modules loaded: none.

何がうまくいかないのですか?

4

1 に答える 1