1

In Haskell, how would one go about writing to an arbitrarily large number of files?

As an example, let's say I want to take the letters a through z and put them in files named for the letter of their contents. An initial attempt was to do the following:

main :: IO ()
main = do
       let letter = map (:"") ['a'..'z']
       zipWith writeFile letter letter

which produced the following error:

Couldn't match expected type 'IO ()' with actual type '[IO ()]'

I feel like there should be a way to loop through a list in a do block, but I haven't been able to find it yet.

martin
  • 1,102
  • 2
  • 12
  • 20
  • Maybe you could fold your `zipWith` with dummy actions so that you end up with the correct type ? – bli Jun 29 '17 at 09:07
  • @bli The thing I'm struggling with here is that I want the type to be `[IO ()]` since I want to perform multiple IO actions. I feel like there should be a way for the do block to accept a list, or flatten it out for me. – martin Jun 29 '17 at 09:15

1 Answers1

2

The function you need is zipWithM.

Re. way to loop through a list in a do block, there is also a function for this - sequence, so you can write sequence $ zipWith writeFile letter letter.

arrowd
  • 33,231
  • 8
  • 79
  • 110
  • I also had to change the type of main to `main :: IO [()]`, but that did it for me. Thanks. – martin Jun 29 '17 at 09:24
  • 1
    @martin That is an option, though it's more common to leave `main :: IO ()` and add `return ()` as the last entry in the `do` block, after the `zipWithM` line. – chi Jun 29 '17 at 09:33
  • 2
    @martin ...or, even better, use the `zipWithM_` variant which does not even return the useless list of units `[()]` in the first place. – chi Jun 29 '17 at 09:48