如何用writeFile写一个[String]到它?
e.g。我有["one", "two", "three"]
我想进入文件:
one two three
如何使用haskell执行此操作?如果需要,我可以写一个额外的功能。
答案 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)
这并不是说Tarrasch
和prnr
没有说过,但是难以将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
,你可以用putStrLn
或writeFile filename
编写String -> IO ()
prelude函数concat :: [String] -> String
具有正确的类型,但它会产生"onetwothree"
,因此文件或stdout看起来如此:
onetwothree
Prelude函数unlines :: [String] -> String
具有正确的类型,但会产生`“one \ ntwo \ nthree”,文件看起来如此:
一个
2个
三个
您想要的预先设定的前奏[String] -> String
功能是unwords
,Tarrasch
注释;但由于pmr
注释unwords
和unlines
都是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
unlines
和intersperse
具有类似于类似字符串的类型的变体,例如ByteString
和Text
如果你想考虑与传递给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相同。