Hi Mark,

at the end of section 2 of http://www.cse.ogi.edu/~mpj/fds.html you
might want to mention that there is a "standard" work-around whenever a
type constructor is needed but not available: Introduce a newtype.

> import Bits

> class Collects e c where
>    empty  :: c e
>    insert :: e -> c e -> c e
>    member :: e -> c e -> Bool

> instance Eq e => Collects e [] where
>   empty  = []
>   insert = (:)
>   member = elem

Apply the work-around for characteristic functions.

> newtype CharacteristicFunction e = CF {unCF :: e -> Bool}
>
> instance Eq e => Collects e CharacteristicFunction where
>   empty      = CF (\y -> False)
>   insert x c = CF (\y -> x == y || unCF c x)
>   member x c = unCF c x

Apply the work-around for bit sets. The dummy type variable "a" is
needed to make "BitSet b" a type constructor. (I've also generalized
your example from Char to Enum.)

> newtype Bits b => BitSet b a = BS {unBS :: b}
>
> instance (Enum e, Bits b) => Collects e (BitSet b) where
>   empty      = BS (bit 0)
>   insert x c = BS (setBit (unBS c) (fromEnum x))
>   member x c = testBit (unBS c) (fromEnum x)

For the hash-table example I am pretty sure that the work-around works
as well, even though I could not figure out your intended
implementation.

Of course this is just a work-around and does not make functional
dependencies superfluous.

Regards,

Heribert.


Reply via email to