haskelliohaskell-spockhaskell-lucid

Cannot display IO [[String]] in app created in Spock and Lucid


I have an issue with Spock, Lucid and IO in Haskell. I've got a function

f :: MySQLConn -> IO [[String]]

Output of f is result of statement "SELECT * FROM TABLE" with converted [MySQLValue] lists to [String] lists.

Then I want to use function f in Spock to display output in my app. I tried to use something like:

(...)
 get "history" $ lucid $ do 
        let offers = c >>= f
        mapM (mapM (p_ . toHtml) ) offers
(...)

Where c is used to create a connection with DB. But it doesn't work. An error is: "No instance for (Traversable IO) arising from a use of ‘mapM’".

If I try:

 get "history" $ lucid $ do 
        mapM (mapM (p_ . toHtml) ) [["a", "b"], ["1","x"]]

it is correct. So my question is - how can I use the result of f in this app?


Solution

  • I think you can perform the IO action inbetween get and lucid:

     get "history" $ do
            offers <- liftIO $ c >>= f
            lucid $ mapM (mapM (p_ . toHtml) ) offers
    

    With liftIO from Control.Monad.IO.Class.