Final project - Servant question

67 views
Skip to first unread message

marin....@gmail.com

unread,
Jan 14, 2018, 11:31:45 AM1/14/18
to Haskell-FER
So I have this code

import HomeController 

type API = "index" :> Get '[HTML] Html

index :: Html  --Text.Blaze.Html.Html
index = HomeController.index 

indexIO :: IO Html
indexIO = HomeController.indexIO 

server :: Server API
server = return index  --this works

but if I write "server = indexIO" instead of "server = return index", than it does not work

Error is 

Couldn't match type `IO  with ` (blaze-markup-0.8.0.0:Text.Blaze.Internal.MarkupM ())'
 Expected type: Server API
      Actual type: IO Html


My problem is that wreq returns IO (something), I use that with scalpel and get IO (something else) and when I create Html with blaze, I get IO Html and I don't know how to use that with servant.





Luka Hadžiegrić

unread,
Jan 14, 2018, 2:17:56 PM1/14/18
to Haskell-FER
This might be a bit confusing since there are some type aliases involved. You are basically within the Server monad (or actually Handler monad or something like that, I don't quite remember). Since you are within another monad you can't just freely execute actions that are available in another monad (which is why we use monads, to limit what can be done within given context). However, this particular monad actually implements `MonadIO` type class which allows us to convert IO action into some other action. So import `liftIO` which will enable you to convert IO action to another action like this :

import Control.Monad.IO.Class ( liftIO )

And than instead of `server = indexIO` write

server = liftIO indexIO

Since you are within a different monad you are actually returning something like :

Server (IO Html)

Instead of just

Server Html

And even if Server was an IO monad, using return on something of type `IO Html` would give you

IO (IO Html)

You can read more about executing IO in servant over here :

Marin Luketin

unread,
Jan 16, 2018, 3:13:19 AM1/16/18
to Haskell-FER
Thank you for the answer

Luka Hadžiegrić

unread,
Jan 16, 2018, 3:16:38 AM1/16/18
to Haskell-FER
If you are interested, you can also checkout natural transformations. They allow you to "automatically convert" monads. This might be a good blog post :

Reply all
Reply to author
Forward
0 new messages