
On Fri, May 16, 2008 at 04:13:35PM +0100, Neil Mitchell wrote:
createProcess :: (StdStream sin, StdStream sout, StdStream serr) => CreateProcess sin sout serr -> IO (Out sin, Out sout, Out serr, ProcessHandle)
Then we could have a static guarantee that we only try to peek at actually-created pipes. I suppose this is a bit heavy infrastructure just to avoid runtime checks for "Just", but in a few years (say, post Haskell'...) it'd be nice to have safer instances like this.
Of course, you can already have these checks without any effort at all, using Catch: http://www-users.cs.york.ac.uk/~ndm/catch/
But then you'd also have to restrict yourself to Haskell 98, right? Or at least to a subset of ghc's extensions. It's not nearly as nice as a solution in the type checker, since it relies on every user of the library running an extra tool if they want a safe interface. Also, it does nothing to eliminate the actual (admittedly trivial) runtime cost of the use of the Maybe type. Actually, though, now that I think about this, I'm curious... does this mean you intend to teach Catch about this particular interface? Or is it able to sneak into the source code of the library in order to infer that as long as we pass CreatePipe for stdin, the first element of the tuple will be a Just? I suppose it must. Which illustrates another advantage of a type-level solution: it allows programmers to infer the behavior of the function from its type, rather than requiring them to look at either its documentation or its implementation (both of which have significant disadvantages... e.g. either of them might not correctly describe all past and future versions of the library, while it's usually a safe assumption that a type-level constraint will lead to a type-check error on any version of the library that fails to satisfy said constraint). -- David Roundy Department of Physics Oregon State University