My goal is to feed correctly the html function (as define in Spock-core) with a HtmlT m
type (ideally Html ()
). In between I am performing some Network.Http.Simple requests. Apparently my knowledge of Haskell is insufficient, I didn't find the way to force the correct 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)
.
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 ()
Here is my connection function (Auth
is a FromJSON data structure to host authorization key and token)
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 :: 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 ...
. Html ()
is nothing else than HtmlT Identity ()
so my first attempt was to feed lucid with 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? 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.
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.
The relevant types:
Fortunately we have this available:
liftIO :: MonadIO m => IO a -> m a
Two steps to getting your
lucid
function running:txt <- renderTextT document
totxt <- liftIO (renderTextT document)
liftIO
is imported (it probably is already). If not: addimport Control.Monad.IO.Class
to your import list.return
fromreturn html (TL.toStrict txt)
.The following code is working on my machine: