3
votes

this is probably a simple question and I've seen a similar one on SO, but I'm still stuck.

I'm trying to do an HTTP call to pull in the contents of another blog and display it on my page. This is more of a learning exercise than anything.

Here's my handler

blog :: App1Handler ()
blog = do
  contents <- Requester.getUrl "http://someblog.com/"
  heistLocal (bindString "contents" contents) . render $ "blog"

Requester.getUrl has the signature getUrl :: String -> IO T.Text

And the error I get back is

src/Main.hs:50:15:
Couldn't match expected type Handler App1 App1 t0' with actual typeIO T.Text'
In the return type of a call of `getUrl'
In a stmt of a 'do' block:
contents <- getUrl "http://someblog.com/"
In the expression:
do { contents <- getUrl "http://someblog.com/";
heistLocal (bindString "contents" contents) . render $ "blog" }

From what I gather, I'm stuck inside of the IO monad and it wants the type Handler App1 App1 t0. I've experimented with sticking liftIO in places, but I'm pretty confused on this one.

Can anyone point me in the right direction?

Thanks!

1
Assuming App1Handler is a typical monad stack supporting IO, it should just be contents <- liftIO $ Requester.getUrl "http://someblog.com/". Have you tried that?hammar
Well, I'll be. I was totally confused. I thought that if contents was type IO(a) then I'd want to lift `heistLocal (bindString "contents")' over it like a functor. Thanks hammar, I've got some reading to do. Also, I appreciate all your answers on here - i keep running into questions that you've answered!Brian

1 Answers

6
votes

You just have to liftIO the IO action returned by getUrl, like this:

contents <- liftIO $ Requester.getUrl "http://someblog.com/"

The reasoning here is simple. You have a do-block of type App1Handler (), which means that the right hand side of any <- statement within this do-block must have type App1Handler a.

However, getUrl returns IO Text, so you need to a function to convert from IO a to App1Handler a which is exactly what liftIO does.

liftIO :: MonadIO m => IO a -> m a