Hello,

I'm writing a small Haskell library for functional reactive programming. The core of the library consists of two data types and several primitives. However, I have programmed this core *twice*: once as a *model* that displays the intended semantics, and once as the actual *implementation* to be used in production code.

Of course, I would like to use QuickCheck to test that the implementation gives the same results as the model. My problem is: how to organize this with the minimum amount of boilerplate?

It appears that I can use *multiparameter type classes* to solve this, but I'm not sure I'm happy with this, in particular because it makes the generated Haddock less readable (see 3) below). On the other hand, I could also use *record wildcards* to conveniently reify a module into a record data structure. But that will give me problems with combinators that are derived from the core combinators (see 2) below).

Haskell Café, what are your suggestions and ideas?


In particular, I wish to:

1) Write examples to be QuickChecked only once.
I imagine that my main function for testing looks like this

    test_equal example =
      forAll $ \input -> example model input
                      == example implementation input

where example an expression involving the combinators from my library. The point is that I don't want to write example twice, once for each version.

2) Use derived combinators.
For reference, here the full signature of the core combinators:

   data Event a
   data Behavior a

   instance Functor Behavior
   instance Applicative Behavior
   instance Functor Event
   instance Monoid  (Event a)

   filter :: (a -> Bool) -> Event a -> Event a
   apply  :: Behavior (a -> b) -> Event a -> Event b
   accumB :: a -> Event (a -> a) -> Behavior a

When writing tests, I also want to use common derived combinators, like, say

   filterJust :: Event (Maybe a) -> Event a
   filterJust = fmap fromJust . filter isJust

without implementing them twice.

3) Obtain readable Haddock.
I like the simplicity and readability of an ordinary module signature. In contrast, libraries with many type class scare me. Or is there a way to make this less scary?

I'm not sure about the last one:
4) Make both model and implementation available to the user,
so that he can QuickCheck his own programs as well. Since the implementation makes heavy use of IO, it is a bit harder to test automatically, so the model might be useful to have.


Best regards,
Heinrich Apfelmus

--
http://apfelmus.nfshost.com


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to