1

我的目标是正确地提供带有HtmlT m类型(理想情况下)的 html 函数(如 Spock-core 中定义的那样Html ())。在这之间,我正在执行一些 Network.Http.Simple 请求。显然我对Haskell的了解不够,我没有找到强制正确单子的方法。据我所知(并理解 monad 的全部含义),没有办法组成不同的 monad,例如(Monad M, Monad N => M a -> (a -> N b) -> N b).

我设法实现的最好的方法是设置一个HtmlT IO ()类型,但后来我陷入了转换功能lucid :: HtmlT IO () -> SpockAction dtb sess state ()

这是我的连接函数(Auth是托管授权密钥和令牌的 FromJSON 数据结构)

     connect :: IO Auth
     connect = do  
                ...building a http request.. 
                response <- httpJSON request
                return (getResponseBody response :: Auth)

接下来,这将连接到getRequest类型的函数中String -> HtmlT IO ()

    getRequest :: RequestPath -> HtmlT IO ()
    getRequest rpath = do
                    atoken <- liftIO connect
                    request' <- liftIO parseRequest "http://......"
                    let request = { series of set methods
                                    to build the request }
                    response <- httpLBS request
                    liftIO (L8.putStrnLn $ (getResponseBody response))

在这里我们来到 lucid 函数,Lucid 可以处理转换Html () -> SpockAction ...Html ()无非HtmlT Identity ()如此,我的第一次尝试是用HtmlT IO ().

   lucid :: HtmlT IO () -> SpockAction database session state ()
   lucid document = do 
                        txt <- renderTextT document       --> inside IO (?)
                        return html (TL.toStrict txt)     <-- naive attempt to 
                                      return to "somewhere" of course stupid..

也许IO不是这里的好单子?当我尝试 Identity monad (拥有 a HtmlT Identity ())时,如果我将 connect 定义为,connect :: Identity Auth那么自然会要求我提供 Identity 的 FromJSON 实例(由使用 httpJSON 引起),一旦我进入 Identity monad,这可能是一个潜在的解决方案我能够将事情连接起来,并可能以一个干净的Html ()类型完成,然后我的 lucid 函数将顺利执行。

感谢您提供任何线索或提示,也许我的方法是完全错误的,我正在做的整个事情是查询一个 restAPI 网站并在使用 Spock 运行的 Web 服务器上查看结果。

4

1 回答 1

1

相关类型:

document :: HtmlT IO ()
renderTextT :: Monad m => HtmlT m a -> m Text
renderTextT document :: IO Text
<the value you need> :: SpockAction database session state Text

幸运的是,我们有这个:liftIO :: MonadIO m => IO a -> m a

让你的lucid函数运行的两个步骤:

  1. 更改txt <- renderTextT documenttxt <- liftIO (renderTextT document)
  2. 尝试编译您的代码以确保liftIO已导入(可能已经导入)。如果没有:添加import Control.Monad.IO.Class到您的导入列表。
  3. return从中删除return html (TL.toStrict txt)

以下代码在我的机器上运行:

lucid :: HtmlT IO () -> SpockAction database session state ()
lucid document = do
  txt <- liftIO (renderTextT document)
  html (TL.toStrict txt)
于 2019-05-31T03:23:15.793 回答