[Haskell-cafe] Painful Data Abstraction

Ryan Ingram ryani.spam at gmail.com
Wed Apr 8 01:39:06 EDT 2009

On Tue, Apr 7, 2009 at 6:11 PM, Brad Larsen <brad.larsen at gmail.com> wrote:
>   prop_insert_idempotent :: (Eq d, PrefixDict d) => d -> Word -> Bool
>   prop_insert_idempotent d w = insert w d' == d'
>     where d' = insert w d
> The problem is this:  I can't think of a non-kludged way of checking that
> TrieDict and ListDict satisfy this abstract property without having to add
> explicit type signatures, e.g.
>   quickCheck (prop_insert_idempotent :: TrieDict -> Word -> Bool)

This is one place where parametrized modules would come in handy.
There hasn't been a good proposal to implement these in Haskell; in
particular it's not clear how they should interact with typeclasses.

You can do something like this:

> data Proxy d = Proxy

> -- add any other constraints required by your test properties here
> data CheckPrefixDict = forall d. (PrefixDict d, Eq d, Show d, Arbitrary d) => CheckPrefixDict (Proxy d)

> prop_insert_idempotent :: CheckPrefixDict -> Property
> prop_insert_idempotent (CheckPrefixDict (Proxy :: Proxy d)) = property prop where
>     prop :: d -> Word -> Bool
>     prop d w = insert w d' == d'
>        where d' == insert w d

> checkableTrie = CheckPrefixDict (Proxy :: Proxy TrieDict)

You then can "quickCheck (prop_insert_idempotent checkableTrie)"

Or if you want to test all your structures at once, make
CheckPrefixDict an instance of Arbitrary that selects one of the
implementations randomly.  (In this case you probably want to add a
descriptive string so that when a test fails you know which instance
has the problem :)

  -- ryan

More information about the Haskell-Cafe mailing list