gpt4 book ai didi

Haskell 写入文件

转载 作者:行者123 更新时间:2023-12-04 02:57:30 25 4
gpt4 key购买 nike

初学者。有一个名为 HHtml 的模块输出以下内容:

  setDoc = "<!DOCTYPE = <html><head>"
setTitle = "<title>" ++ htmlTitle generator ++ "</title>"
setHeader = "<header>" ++ htmlHeader generator ++ "</header>"
setMeta = "<meta>" ++ htmlMeta generator ++ "</meta></head>"
setBody = "<body>" ++ htmlBody generator ++ "</body>"
setFooter = "<footer>" ++ htmlFooter generator ++ "</footer>"
setEOF = "</html>"

setHTML = [setDoc, setTitle, setHeader, setMeta, setBody, setFooter, setEOF]

主文件:
import HHtml
import System.IO

main = do
let content = mapM_ putStrLn setHTML
writeFile "index.html" content

但是现在我看着它,我不断得到 Couldn't match type IO() with [Char]或任何变体。我理解错误消息,但我对修复它感到非常困惑。谢谢指点!

最佳答案

mapM_ putStrLn setHTMLIO () 类型的操作,您将其分配给一个名称 contentlet陈述。执行时,此操作将打印 setHTML 的每一行,什么也不返回。您可以通过编写如下内容来执行此操作:

main = do
let content = mapM_ putStrLn setHTML
content

没有变量,这只是:
main = mapM_ putStrLn setHTML

但是 content是一个不透明的值——你唯一能做的就是从 main 执行它。 ,加入其他 IO >>= 的操作(或 do 符号),并将其存储在数据结构中(此处不需要)。特别是,它不“存储”页面的内容,它只是向运行时描述它应该如何打印该内容。无论如何,您注意到的类型不匹配: writeFile接受 String ,又名 [Char] ,这显然不是 IO () .

但是由于您显然想使用 writeFilesetHTML的每一行到一个文件,而不是标准输出,你不想要一个打印行的 Action ——你想要行本身,用换行符连接在一起。有几种可能的方法可以做到这一点,具体取决于您希望如何扩展此代码。

一种方法是使用 unlines :: [String] -> String函数将行与换行符连接在一起,然后使用 writeFile写出结果 String"index.html" :
main = writeFile "index.html" (unlines setHTML)

如果您想将连接的内容放在变量中,您当然可以这样做:
main = do
let content = unlines setHTML
writeFile "index.html" content

(实际上,如果您不需要 unlines 成为 setHTML,则可以将 setHTML 调用移至 [String] 的定义中。)

现在 writeFile将接受 content因为它是 String值,而不是 IO ()行动。这是一个很好的方法,因为它保持构建页面的逻辑纯粹,并且只使用 IO根据实际编写页面的需要。

或者,您可以采取更紧迫的方法,留在 IO .那么一个好用的函数是 withFile (来自 System.IO ),它具有以下类型:
FilePath -> IOMode -> (Handle -> IO r) -> IO r

它需要一个 FilePath打开, 一个 IOMode (例如 ReadModeWriteMode )来指示您是否将读取或写入句柄,以及接受句柄并执行某些操作的函数 IO并返回某种类型的结果 r ;它返回一个 IO打开文件、运行函数、自动确保文件关闭(即使抛出异常)并返回结果的操作。

然后你会使用 mapM_以类似于您已经拥有的方式,将每一行打印到该句柄 - 为此,有 hPutStrLn :: Handle -> String -> IO ()写入特定句柄,而不是 putStrLn写入标准输出。精简版:
main = withFile "index.html" WriteMode $ \file -> do
mapM_ (hPutStrLn file) setHTML

如果您不喜欢 lambda 的外观,或者更详细的版本:
main = withFile "index.html" WriteMode writeContents
where writeContents file = mapM_ (hPutStrLn file) setHTML

关于Haskell 写入文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52290934/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com