Haskell Servant和MTL应用程序样式

时间:2018-09-15 07:51:38

标签: haskell servant

在我观看了George Wilson(下一级MTL https://github.com/gwils/next-level-mtl-with-classy-optics/blob/master/Slides.pdf)的精彩演讲后,我尝试创建使用MTL样式设计并决定使用仆人的应用程序,看起来该库没有不太适合这种设计。
下面的代码无法编译,因为我无法将 m 转换为Handler。

getItems :: (MonadIO m, MonadReader r m, HasNetworkConfig r) => m [Item]
getItems =
   return [Item "foo" "bar"]

mkApp :: Application
mkApp = serve itemApi getItems

您可以在此处找到完整的示例:https://github.com/paweln1986/ServantMTLStackOverflowExample

可以与仆人一起使用任何monad吗?如何实现呢?我尝试使用hoistServer失败。你知道我在这里想念什么吗?

编译错误:

   • No instance for (MonadReader r0 Handler)
    arising from a use of ‘getItems’
   • In the second argument of ‘serve’, namely ‘getItems’
     In the expression: serve itemApi getItems
     In an equation for ‘mkApp’: mkApp = serve itemApi getItems
   |
40 | mkApp = serve itemApi getItems
   |                       ^^^^^^^^

更短的例子:

type ReaderAPI = "ep1" :> Get '[JSON] Int :<|> "ep2" :> Get '[JSON] String    :<|> Raw :<|> EmptyAPI

readerApi = Proxy :: Proxy ReaderAPI

readerServer :: (MonadIO m, HasNetworkConfig r, MonadReader r m) => ServerT ReaderAPI (AppT m)
readerServer = return 1797 :<|> view (networkConfig . host) :<|> Tagged (error "raw server") :<|> emptyServer

nt x = return undefined

mainServer = hoistServer readerApi nt readerServer :: Server ReaderAPI

这给了我下面的编译错误

    • Ambiguous type variable ‘m0’ arising from a use of ‘readerServer’
  prevents the constraint ‘(MonadIO m0)’ from being solved.
  Probable fix: use a type annotation to specify what ‘m0’ should be.
  These potential instances exist:
    instance [safe] MonadIO IO -- Defined in ‘Control.Monad.IO.Class’
    instance MonadIO m => MonadIO (AppT m) -- Defined in ‘Types’
    instance MonadIO Handler
      -- Defined in ‘Servant.Server.Internal.Handler’
    ...plus 18 instances involving out-of-scope types
    (use -fprint-potential-instances to see them all)
• In the third argument of ‘hoistServer’, namely ‘readerServer’
  In the expression:
      hoistServer readerApi nt readerServer :: Server ReaderAPI
  In an equation for ‘mainServer’:
      mainServer
        = hoistServer readerApi nt readerServer :: Server ReaderAPI
   |
64 | mainServer = hoistServer readerApi nt readerServer :: Server ReaderAPI
   |                                       ^^^^^^^^^^^^

1 个答案:

答案 0 :(得分:3)

最后,我设法解决了我的问题。

$first = '.$chartrow["firstpl_score1"].';
$second = '.$chartrow["2ndpl_score1"].';
$third = '.$chartrow["3rdpl_score1"].';

我错过的一件事是正确使用了hoistServer。在创建了正确的从monad(AppT)到Handler的自然转换之后,所有内容都会按预期进行编译和运行。