3

I find first example of Shake usage demonstrating a pattern that seems error prone:

    contents <- readFileLines $ out -<.> "txt"
    need contents
    cmd "tar -cf" [out] contents

Why do we need need contents when readFileLines reads them and cmd references them? Is this so we can avoid requiring ApplicativeDo?

sevo
  • 4,559
  • 1
  • 15
  • 31
  • I've tried to elaborate in an answer, but I'm not sure I've really got to the heart of the question. What do you see as the potential error? How do you think `ApplicativeDo` might help? – Neil Mitchell Feb 29 '16 at 19:41
  • @Neil, thanks for being open minded :) So here's my view. From someone not experienced in Haskell, any seemingly "unnecessary" code raises questions like "Why do you recommend writing it this way"? Is this solving a lazy IO problem? Is this how you adapt parallel tasks to a `Monad` interface (compared with `Haxl` use of `ApplicativeDo`)? Why not define `tar` goal with proper semantics on input files instead? I may be overly cautious about complex Haskell stuff underneath `Shake` though. – sevo Feb 29 '16 at 22:26
  • 1
    so are you asking why the `need` is necessary? It's necessary because you have to tell Shake what `tar` will use, because it has no idea what `tar` does. You are right, people could define `tar inp out = do need inp; cmd "tar -cf" [out] inp` - and indeed in a larger build system I would encourage that. – Neil Mitchell Mar 01 '16 at 11:33

1 Answers1

2

I think part of the confusion may be the types/semantics of contents. The file out -<.> "txt" contains a list of filenames, so contents is a list of filenames. When we need contents we are requiring the files themselves be created and depended upon, using the filenames to specify which files. When we pass contents on to cmd we are passing the filenames which tar will use to query the files.

So the key point is that readFileLines doesn't read the files in question, it only reads the filenames out of another file. We have to use need to make sure that using the files is fine, and then we actually use the files in cmd. Another way of looking at the three lines is:

  1. Which files do we want to operate on?
  2. Make sure those files are ready.
  3. Use those files.

Does that make sense? There's no relationship with ApplicativeDo - it's presence wouldn't help us at all.

Neil Mitchell
  • 9,090
  • 1
  • 27
  • 85