Chetan Yewale
Chetan Yewale

Reputation: 312

Convert a Monadic value to Non-monadic

I am new to Haskell. I need to read the contents from a directory (i.e list all the files in the directory) and convert it to HTML. I have a codebase which uses the Yesod framework.

Now, I was able to read the directory contents using getDirectoryContents which returns type of IO [FilePath]. I want to be able to represent this in HTML.

Can someone help me on this? So far this is what I have tried. The error that I get is: Couldn't match type ‘IO’ with ‘Text.Blaze.Internal.MarkupM’ Expected type: Text.Blaze.Internal.MarkupM Html Actual type: IO Html

Please check the code below:

{-# LANGUAGE OverloadedStrings     #-}
{-# LANGUAGE QuasiQuotes           #-}
{-# LANGUAGE TemplateHaskell       #-}
{-# LANGUAGE TypeFamilies          #-}

import Yesod.Core
import Text.Blaze.Html (toValue, (!))
import qualified Text.Blaze.Html5 as H
import qualified Text.Blaze.Html5.Attributes as HA
import System.Directory as FS



getTestHamletR = defaultLayout $ do
    setTitle "Test Hamlet"
    toWidget $ \render -> do
           H.p $ do
                result <- fmap toHtml $ getListOfFiles "/home/chetan"
                result

Here is the getListOfFiles function:

getListOfFiles::FilePath -> IO [FilePath]
getListOfFiles fpath = FS.getDirectoryContents fpath

Upvotes: 0

Views: 178

Answers (1)

ondra
ondra

Reputation: 9331

I'm not well versed in Yesod, but this should work.

You cannot convert an IO value to non-IO value. However, you can work with these values, while staying in IO. To say it somewhat incorrectly, you can work with these values while being inside IO. I.e. this should work (not-tested):

getTestHamletR = do
    files <- liftIO $ getListOfFiles "/home/chtan"
    defaultLayout $ do
        setTitle "Test Hamlet"
        toWidget $ \render -> do
           H.p $ toHtml (intercalate ", " files)

I guess that getTestHamletR is not directly IO, but it is some layer above IO, so we can use liftIO to convert the IO [FilePath] to m [FilePath] where m is the Monad yesod uses.

The getTestHamletR is an IO function - every line works inside IO, you get the directory contents as IO [FilePath] and you essentially convert it to IO Html.

Upvotes: 3

Related Questions