将 Monadic 值转换为 Non-monadic

Convert a Monadic value to Non-monadic

我是 Haskell 的新手。 我需要从目录中读取内容(即列出目录中的所有文件)并将其转换为 HTML。 我有一个使用 Yesod 框架的代码库。

现在,我可以使用 getDirectoryContents returns 类型的 IO [FilePath] 读取目录内容。我希望能够在 HTML.

中表示这一点

有人可以帮我解决这个问题吗?到目前为止,这是我尝试过的。 我得到的错误是: Couldn't match type ‘IO’ with ‘Text.Blaze.Internal.MarkupM’ Expected type: Text.Blaze.Internal.MarkupM Html Actual type: IO Html

请检查以下代码:

{-# 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

这里是 getListOfFiles 函数:

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

我不太熟悉 Yesod,但这应该有用。

您不能将 IO 值转换为 non-IO 值。但是,您可以使用这些值,同时保持 IO。说得有点不对,您可以在 IO 内部使用这些值。 IE。这应该有效(not-tested):

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

我猜getTestHamletR不是直接IO,而是在IO之上的某个层,所以我们可以用liftIO转换IO [FilePath]m [FilePath] 其中 m 是 Monad yesod 使用的。

getTestHamletR 是一个 IO 函数 - 每行都在 IO 中工作,您得到的目录内容为 IO [FilePath] 并且您实际上将其转换为 IO Html.