3 ms·
Regarding your example, I think that one part of the problem (which you mentioned in the first paragraph of your comment) is that you are still a novice. I can
by gnuvince 14y ago
Regarding your example, I think that one part of the problem (which you mentioned in the first paragraph of your comment) is that you are still a novice. I cannot claim to be an expert in FP or Haskell, but here's how I would go about your problem.
First, I think your problem really has two tasks to perform: getting a list of files that don't exist, and selecting only a part of those inexistant files. It would make sense to decompose these two tasks into two different functions, and since Haskell has non-strict evaluation, we don't have to worry about generating too much data (list of inexistant files) for nothing. Starting with the function to select inexistant files:
inexistantFiles :: [FilePath] -> IO [FilePath]
inexistantFiles files = filterM (\f -> doesFileExist f >>= return . not) files
Some Haskellers may prefer to write their functions completely point-free, but I like to have my variables in the code if it helps me read the coder better. And then we can write another small function to select only the `n` first inexistant files:
takeInexistantFiles :: Int -> [FilePath] -> IO [FilePath]
takeInexistantFiles n files = takeM n (inexistantFiles files)
where takeM n = liftM (take n)
(Surely, we'd prefer to just write `takeM` and call it directly on the result of `inexistantFiles`, but I prefered to go with the specialized function.) Someone who knows Haskell better than I do could certainly come up with a cleaner solution, but I think the code is readable, solves the problem you mentioned and isn't any harder to understand than the equivalent imperative code.
Have a Merry Christmas!
- Maro 14y agoThanks, great comment.
- mifrai 14y agoand since Haskell has non-strict evaluation, we don't have to worry about generating too much data (list of inexistant files) for nothing. Be careful here. Because you're in the IO monad, the entire list of files will always be computed first (ie. doesFileExist will be called for every file given). Non-strict doesn't really buy you much here. The "expensive" operation here will always be executed. At most, you're avoiding converting some list-consing-thunks to a list.
- deleted 14y ago[deleted]