How to write each [String] with writeFile to a file in haskell?

how can i write with writeFile a [String] into it?

eg. I have ["one", "two", "three"]

and I want to get to the file:

 one two three 

how to do it with haskell? I can write an additional function if necessary.

+4
source share
4 answers

I would suggest using unwords :: [String] -> String instead of using intersperse . I would just like to answer a simple example using ghci :

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

It doesn’t say anything Tarrasch and prnr said nothing, but the difficulty arises from the fact that we do not separate IO from pure functions: you say

I have ["one", "two", "three"] and I want this in the file: one two three .

You have a list of lines and you want to do something, i.e. you are looking for the function lkndfhu :: [String] -> IO () . True, but if you ask:

What do I want to write to a (new) file?

You will notice that this is the same as in this case:

What do I want to write in stdout?

What do I want to add to file.txt?

Well, this is "one two three" :: String . You want something that maps ["one", "two", "three"] to "one two three" , ignore what you are going to do with "one two three"

So, you are looking for the function lkndfhu_pure :: [String] -> String , which you can create with putStrLn or writeFile filename , which are of type String -> IO ()

Well, the prelude function concat concat :: [String] -> String is of the correct type, but it will give "onetwothree" , and the file or stdout looks like this:

onetwothree

The function Prelude unlines :: [String] -> String has the desired type, but will give `` one \ ntwo \ nthree ', and the file will look like this:

one
two
three

The supposed function Prelude [String] -> String that you want is unwords , as Tarrasch marks; but as pmr notes unwords and unlines both compositions concat :: [[a]] -> [a] with intersperse :: a -> [a] -> [a] - basically:

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

or, equivalently,

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

(These are not the definitions actually used by the prelude.) As pmr notes, the intersperse abstraction means that it can be used with IO complex ways, but there is no indication that this is what you need. Note that unwords unlines and intersperse have options for string types like Fancier. ByteString and Text

If you want to think about preparing a document that is compatible with using pure functions before passing to IO, you can look at the pretty printed library that comes with the Haskell platform (there are many others). in ghci type :m +Text.PrettyPrint , then type: browse. ghci (and Hugs ) implements the Doc type in a special way, so when evaluating an expression, Doc displayed, as it appears to the reader if you pass it to a string and write it to a file:

  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) 

These examples are, of course, quite primitive, check out all the crazy features with :browse and examples in the docs

+10
source

Use interperse to get spaces between words and add each line to the list in a file in path , where xs is your list of words:

 mapM_ (appendFile path) (intersperse " " xs) 

It’s probably faster to smooth the list of lines and write it right away:

 writeFile path (concat (intersperse " " xs)) 

Although the first seems to me more natural.

Edit: Note that the first and second options still do different things if the file already contains something. writeFile will simply write a new file, and appendFile will add to existing content. It is unclear what kind of behavior you really want.

+4
source

I am surprised that no one mentioned intercalating, the same thing as concat and interperse.

0
source

All Articles