如何用writeFile将每个[String]写入haskell中的文件?

时间:2011-04-23 12:50:14

标签: haskell io

如何用writeFile写一个[String]到它?

e.g。我有["one", "two", "three"]

我想进入文件:

one two three

如何使用haskell执行此操作?如果需要,我可以写一个额外的功能。

4 个答案:

答案 0 :(得分:12)

我建议使用unwords :: [String] -> String而不是intersperse。我想简单回答一下这个简单的例子,使用ghci

Prelude> let ss = ["one", "two", "three"]
Prelude> writeFile "myfile" $ unwords ss
Prelude> readFile "myfile"
"one two three"

答案 1 :(得分:10)

这并不是说Tarraschprnr没有说过,但是难以将IO从纯函数中分离出来:你说

  

我有["one", "two", "three"],我希望将其放入文件中:one two three

你有一个字符串列表,并希望做一些事情,即你正在寻找一个函数lkndfhu :: [String] -> IO ()。确实如此,但如果你问:

  

我想写一个(新)文件是什么意思?

你会注意到它与这种情况相同:

  

我想写什么东西到stdout?

     

我想要附加到文件file.txt的内容是什么?

嗯,这是"one two three" :: String。您需要将["one", "two", "three"]映射到"one two three"的内容,不要介意使用"one two three"

进行操作

所以你真的在寻找一个函数lkndfhu_pure :: [String] -> String,你可以用putStrLnwriteFile filename编写String -> IO ()

类型的函数

prelude函数concat :: [String] -> String具有正确的类型,但它会产生"onetwothree",因此文件或stdout看起来如此:

  

onetwothree

Prelude函数unlines :: [String] -> String具有正确的类型,但会产生`“one \ ntwo \ nthree”,文件看起来如此:

  

一个
  2个
  三个

您想要的预先设定的前奏[String] -> String功能是unwordsTarrasch注释;但由于pmr注释unwordsunlines都是concat :: [[a]] -> [a]intersperse :: a -> [a] -> [a]的组合 - 基本上是:

 unwords mystrings = concat (intersperse " " mystrings)
 unlines mystrings = concat (intersperse "\n" mystrings)

或等同地

 unwords  = concat . intersperse " " 
 unlines  = concat . intersperse "\n" 

(这些不是Prelude实际使用的定义。)正如pmr注意到,intersperse的抽象性意味着它可以用IO以复杂的方式使用,但有没有迹象表明这是你需要的。请注意,unwords unlinesintersperse具有类似于类似字符串的类型的变体,例如ByteStringText

如果你想考虑与传递给IO之前使用纯函数一致的文档准备,你可能会看看Haskell平台附带的漂亮的打印库(还有很多其他的)。在ghci类型:m +Text.PrettyPrint中,然后键入:browse。 ghci(和Hugs)以特殊方式实现Doc类型,因此评估表达式会显示Doc,因为如果您将其呈现给字符串并将其写入文件:

 PrettyPrint> let lknfdhu_strings = ["one", "two", "three"]
 PrettyPrint> :t lknfdhu_strings
 lknfdhu_strings :: [String]
 PrettyPrint> let lknfdhu = map text lknfdhu_strings
 PrettyPrint> :t lknfdhu
 lknfdhu :: [Doc]
 PrettyPrint> hcat lknfdhu
 onetwothree
 PrettyPrint> hsep lknfdhu
 one two three
 PrettyPrint> vcat lknfdhu
 one
 two
 three
 PrettyPrint> let looksGood = hsep lknfdhu
 PrettyPrint> :t render
 render :: Doc -> String
 PrettyPrint> render looksGood
 "one two three"
 PrettyPrint> render (vcat lknfdhu)
 "one\ntwo\nthree"
 PrettyPrint> let dash =  " - " 
 PrettyPrint> let dashdoc = text dash
 PrettyPrint> dash
 " - "
 PrettyPrint> dashdoc
  - 
 PrettyPrint> hcat ( punctuate dashdoc lknfdhu )
 one - two - three
 PrettyPrint> hcat ( punctuate (text "   ") lknfdhu )
 one   two   three
 PrettyPrint> writeFile "lknfdhu.txt" (render looksGood)

这些示例当然非常原始,请查看所有使用:browse的疯狂函数以及文档中的示例

答案 2 :(得分:4)

使用intersperse获取单词之间的空格,并将列表中的每个字符串附加到path处的文件中,其中xs是您的单词列表:

mapM_ (appendFile path) (intersperse " " xs)

将字符串列表展平并立即写入可能会更快:

writeFile path (concat (intersperse " " xs))

虽然第一个对我来说更自然。

编辑:请注意,如果文件已包含某些内容,则第一个和第二个变体仍会执行不同的操作。 writeFile只会在appendFile附加到现有内容时编写新文件。目前尚不清楚你真正想要的行为。

答案 3 :(得分:0)

我很惊讶没有人提到插入,这与concat和intersperse相同。