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 aTwo steps to getting your
lucidfunction running:txt <- renderTextT documenttotxt <- liftIO (renderTextT document)liftIOis imported (it probably is already). If not: addimport Control.Monad.IO.Classto your import list.returnfromreturn html (TL.toStrict txt).The following code is working on my machine: