Peaker•

I've long described the problem of make as being Applicative rather than Monadic and got empty stares.

Now have a page to refer them to :)

8
ndmitchellOP•

That was the main motivation in writing the post. It seemed unfair for me to tell people that "Shake was Monadic", but not have anywhere people could even begin to understand what that meant.

3
maxiepoo_•

Not really relevant to the article, but I had a question about Shake.

Why does the only run interface take a Rules () and return an IO () instead of taking a Rules a and returning IO a? I was looking at using it as a library for the elm build system but needed to determine some information at build time (can't remember the specifics).

3
nominolo•

The basic approach is to write all the data you need into files.

  • Have something that computes your rules: myRules :: Rules ()

  • Create the result you want in a file:

    runShake ... $ myRules >> want ["file"]
    result <- parseFile "file"
    doStuffWith result
    

You can also do recursive traversals in this style. For example, to collect all files in a project (reachable from the project roots):

 "//*.dep" *> \out -> writeFile out =<< computeDirectDeps (out -<.> "src")
 "//*.deps" *> \out -> do
     imports <- readFile (out -<.> "dep")
     -- "recursive" call
     depss <- mapM (readFile . (-<.> "deps")) imports
     writeFile out (nub (concat depss))
 "//.projectdeps" *> \out ->
     roots <- getProjectRootModules
     depss <- mapM (readFile . (-<.> "deps")) roots
     writeFile out (nub (concat depss))

There's probably a way to wrap this up in a nicer higher-level API.

3
ndmitchellOP•

The fact that Rules takes any type argument is mostly there so you can have a Monad instance for Rules, but morally it's a Monoid. Shake usually refers to Rules (). I could make it Rules a to IO a, but you'd have to compute the a value without referring to anything in Shake, since the Rules cannot obtain any information about actions.

If you can dig up the specific problem that you had with elm (or even if you can fake up something based on what you can remember now), I suggest you ask it on StackOverflow.

2
maxiepoo_•

I think it might have been something as simple as trying to tell whether or not type checking passed.

1
ndmitchellOP•

You can throw exceptions from Shake actions, which bubble up to the thing that called shake, which might be how you indicate type checking failed.

1