[Haskell-cafe] Re: ANNOUNCE: HNOP 0.1

David Roundy droundy at darcs.net
Sat Jul 1 09:04:40 EDT 2006

On Fri, Jun 30, 2006 at 02:52:54PM -0700, Ashley Yakeley wrote:
> I'm currently considering possible unit tests, since right now I rely 
> solely on code inspection. One possibility would be to simply time the 
> function to show that it didn't have time to do anything really long at 
> least. But that's not very satisfactory, since that is strictly a 
> performance test, not a functionality test. It's like any other Haskell 
> function: I want to implement it as efficiently as possible, but I don't 
> guarantee any particular performance.
> Ideally I would have tests like these:
> * Verify noop does nothing with the file system.
> * Verify noop does no networking activity.
> * Verify noop makes no use of stdin/stdout/stderr.
> * Verify noop does not modify any external IORefs.
> etc.

I think the best approach for this kind of verification would be to
break the IO monad up into classes, and then write a polymorphic
function, as this would allow you to verify that your noop function
behaves as expected,

class Monad m => FileWriteMonad m where
  writeFile :: FilePath -> String -> m ()

class Monad m => FileReadMonad m where
  readFile :: FilePath -> m String
  openFileRead :: FilePath -> M Handle -- would be more general with AT

class Monad m => NetworkMonad m where
  withSocketsDo :: m a -> m a

class Monad m => RefMonad m where -- note, this could be more general with AT
  newIORef :: a -> m (IORef a)

And then we could catch bugs in the noop function simply by looking at
its type.  e.g. when we saw

noop :: FileReadMonad m => m ()

we'd have a strong suspicion that noop is actually trying to read from
the filesystem, but if the type is just

noop :: m ()

we'd have a high degree of confidence (assuming no unsafePerformIO is
going on) that noop is bug-free.  Unfortunately, even this isn't
sufficient to show that noop will never return bottom...
David Roundy

More information about the Haskell-Cafe mailing list