Reputation: 312
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
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