
Occasionally in library proposals one comes across classes of this form: class Thingy a where foo :: a -> this bar :: a -> that spong :: a -> theotherthing Such classes can be replaced by data-types, which turn out to also be more general: data Thingy = MkThingy { foo :: this, bar :: that, spong :: theotherthing } My question: is there a reason not to use types? I'm particularly interested in two cases that I've come across, references and streams. Here's the class version: class (Monad m) => Ref m r | r -> m, m -> r where newRef :: a -> m (r a) readRef :: r a -> m a writeRef :: r a -> a -> m () class (Monad m) => Stream m h where vPutStrLn :: h -> String -> m () vGetContents :: h -> m String vIsEOF :: h -> m Bool vClose :: h -> m () -- etc. And here's the type version: data Ref m a = MkRef { readRef :: m a, writeRef :: a -> m () } class (Monad m) => HasRefs m where newRef :: a -> m (Ref m a) data Stream m = MkStream { vPutStrLn :: String -> m (), vGetContents :: m String, vIsEOF :: m Bool, vClose :: m (), -- etc. } Is there any reason not to prefer using types? -- Ashley Yakeley, Seattle WA WWEWDD? http://www.cs.utexas.edu/users/EWD/