[英]How to stack correctly monads to finally render to html?
My goal is to feed correctly the html function (as define in Spock-core) with a HtmlT m
type (ideally Html ()
). 我的目标是使用HtmlT m
类型(最好是Html ()
)正确地馈送html函数(在Spock-core中定义)。 In between I am performing some Network.Http.Simple requests. 在这之间,我正在执行一些Network.Http.Simple请求。 Apparently my knowledge of Haskell is insufficient, I didn't find the way to force the correct monad. 显然我对Haskell的了解不足,我没有找到强制正确的monad的方法。 As far as I know (and understand the whole sense of monads) there is no way to compose different monads something like (Monad M, Monad N => M a -> (a -> N b) -> N b)
. 据我所知(并理解单子的整体含义),没有办法组成不同的单子,例如(Monad M, Monad N => M a -> (a -> N b) -> N b)
。
The best I manage to achieve was to set up a HtmlT IO ()
type but then I get stuck in the conversion function lucid :: HtmlT IO () -> SpockAction dtb sess state ()
我设法达到的最佳效果是设置HtmlT IO ()
类型,但随后陷入转换函数lucid :: HtmlT IO () -> SpockAction dtb sess state ()
Here is my connection function ( Auth
is a FromJSON data structure to host authorization key and token) 这是我的连接函数( Auth
是用于承载授权密钥和令牌的FromJSON数据结构)
connect :: IO Auth
connect = do
...building a http request..
response <- httpJSON request
return (getResponseBody response :: Auth)
Next this get wired in a getRequest
function of type String -> HtmlT IO ()
接下来,将其getRequest
到类型为String -> HtmlT IO ()
的getRequest
函数中
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))
and here we come to the lucid function, Lucid can handle transformation Html () -> SpockAction ...
. 在这里我们介绍了lucid函数,Lucid可以处理Html () -> SpockAction ...
。 Html ()
is nothing else than HtmlT Identity ()
so my first attempt was to feed lucid with HtmlT IO ()
. Html ()
就是HtmlT Identity ()
所以我的第一个尝试是用HtmlT IO ()
来提供清醒的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..
Maybe IO
is not the good monad here? IO
可能不是这里的好单子吗? When I try the Identity monad (to have a HtmlT Identity ()
) so if I define connect as connect :: Identity Auth
then naturally it follows that I am asked for a FromJSON instance of Identity (arising from using httpJSON), maybe that's a potential solution once I am in the Identity monad I am able to wire things up and probably finish with a clean Html ()
type which will be then executed smoothly by my lucid function. 当我尝试使用Identity monad(具有HtmlT Identity ()
)时,如果我将connect定义为connect :: Identity Auth
那么很自然地,我会被要求输入Identity的FromJSON实例(使用httpJSON引起),也许是潜在的解决方案一旦我进入Identity monad,就可以进行连接,并可能以干净的Html ()
类型结束,然后由我的清醒函数平稳地执行它。
Thank you for any clue or hints, maybe my approach is totally wrong the whole thing I am working on is to query a restAPI website and view the result on a web server run with Spock. 感谢您提供的任何线索或提示,也许我的方法是完全错误的,整个工作是查询restAPI网站并在使用Spock运行的Web服务器上查看结果。
The relevant types: 相关类型:
document :: HtmlT IO ()
renderTextT :: Monad m => HtmlT m a -> m Text
renderTextT document :: IO Text
<the value you need> :: SpockAction database session state Text
Fortunately we have this available: liftIO :: MonadIO m => IO a -> ma
幸运的是,我们有以下可用: liftIO :: MonadIO m => IO a -> ma
Two steps to getting your lucid
function running: 运行lucid
函数的两个步骤:
txt <- renderTextT document
to txt <- liftIO (renderTextT document)
将txt <- renderTextT document
更改为txt <- liftIO (renderTextT document)
liftIO
is imported (it probably is already). 尝试编译您的代码以确保liftIO
已导入(可能已经导入)。 If not: add import Control.Monad.IO.Class
to your import list. 如果不是这样:将import Control.Monad.IO.Class
添加到您的导入列表。 return
from return html (TL.toStrict txt)
. 从return html (TL.toStrict txt)
删除return
。 The following code is working on my machine: 以下代码在我的计算机上运行:
lucid :: HtmlT IO () -> SpockAction database session state ()
lucid document = do
txt <- liftIO (renderTextT document)
html (TL.toStrict txt)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.