
Patrick Browne
{- Below is a *specification* of a queue. If possible I would like to write the equations in type class. Does the type class need two type variables? How do I represent the constructors? Can the equations be written in the type class rather than the instance? -}
(Side note: When opening a new topic, please don't /reply/ to a post, but post it separately by creating a new mail.) The type class needs to know the element type, so your observation is correct. Usually, as in your case, the element type follows from the data structure type, and you will want to inform the type system about this connection. There are basically three ways to do it. The first is using MultiParamTypeClasses and FunctionalDependencies: class Stacklike a s | s -> a where empty :: s a null :: s a -> Bool push :: a -> s a -> s a pop :: s a -> Maybe a size :: s a -> Int tail :: s a -> Maybe (s a) Another way is using an associated type (TypeFamilies). This is cleaner, but much more noisy in the type signatures: class Stacklike s where type StackElement s empty :: s (StackElement s) null :: s (StackElement s) -> Bool push :: StackElement s -> s (StackElement s) -> s (StackElement s) pop :: s (StackElement s) -> Maybe (StackElement s) size :: s (StackElement s) -> Int tail :: s (StackElement s) -> Maybe (s (StackElement s)) Finally once you realize that there is really no need to fix the element type in the type class itself, you can simply write a type class for the type constructor, similar to how classes like Functor are defined: class Stacklike s where empty :: s a null :: s a -> Bool push :: a -> s a -> s a pop :: s a -> Maybe a size :: s a -> Int tail :: s a -> Maybe (s a) The big question is whether you want to write a class at all. Usually classes are used to capture patterns, not operations. Greets, Ertugrul -- Not to be or to be and (not to be or to be and (not to be or to be and (not to be or to be and ... that is the list monad.