[Haskell-cafe] Re: A Monad for on-demand file generation?

David Roundy droundy at darcs.net
Thu Jul 3 14:35:05 EDT 2008


On Thu, Jul 03, 2008 at 07:09:58PM +0100, ChrisK wrote:
> Joachim Breitner wrote:
> > * The 5th line does not have this effect. Because this gets desugared
> >to (>>), the special implementation of (>>) means that the next line
> >still sees the same dependency state as the before the call to liftIO.
> 
> You are violating the monad laws.  (f >> k) and (f >>= \_ -> k)
> should do the same thing.  You might write a version of liftIO that
> has the effect you want, however.

I don't mind a little anarchy in the monad laws...  :)

> > * A change to inFile3 causes outFile1 to be re-written, although from
> >looking at the code, _we_ know that this is not necessary, but the ODIO
> >monad can not tell. The programmer should have swapped the lines.
> 
> Let me reverse engineer your algorithm (aside from the screwy >>):
> 
> Every readFile that is encountered in processing ODIO is added to a
> list of source files.  The reading deferred to be lazy with
> unsafePerformIO.
> 
> When a writeFile is encountered it is assumed to depend on all
> previously read files.  If this output file already exists and is
> newer than all the source files, then writing it is skipped (and
> perhaps also the lazy reads are skipped).  Otherwise, the writing is
> strict.
> 
> ----
> 
> I would say this is an unusual module.  I rather prefer Makefile semantics,
> which could be improved in some ways by using a DSL in Haskell instead.
> 
> The syntactic form of a file-oriented Makefile declaration is
> 
> output : input1 input2
>   shell script
>   more shell script

I must say that I prefer the automatic computation of dependencies as
outlined by Joachim.  A bit more is needed, of course, to enable true
Makefile-like dependency handling, since you'd want to ensure that the
dependencies themselves are up-to-date, but the automatic computation
of dependencies would be a real boon.  Makefiles are extremely prone
to errors in which dependencies are left out, and those bugs are only
caught on rare occasions when the build is performed in an unusual
order, or when a rarely-touched source file is edited.

Of course, to create a "make" replacement, you'd also have to be able
to call external programs and track which files they use, which is a
hard problem, particularly as which files they use may depend on the
contents of the files that they use.  One could, however, lift calls
to well-behaved external programs (e.g. those like ghc or gcc that can
output their dependencies) into this sort of monad.

David


More information about the Haskell-Cafe mailing list