我的目标是正确地提供带有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 服务器上查看结果。