
Bulat Ziganshin:
Hello Lennart,
Sunday, March 19, 2006, 4:05:03 AM, you wrote:
LA> I have to agree with Manuel. I write a lot of Haskell code. LA> People even pay me to do it. I usually stay with Haskell-98,
when i wrote application code, i also don't used extensions very much, i even don't used Haskell-98 very much and afair don't defined any type classes at all
but when i gone to writing libraries, that can be used by everyone, type classes and requirement in even more extensions is what i need permanently. in particular, i try to write library so what any conception (stream, Binary, reference, array) can be used in any monad and that immediately leads me to using MPTC+FD. moreover, problems with resolving class overloading and other deficiencies of current unofficial Hugs/GHC standard are permanently strikes me
Libraries are a means, not an end. The fact still remains. Most programs don't need MPTCs in an essential way. It's convenient to have them, but they are not essential.
i had a class which defines "default" reference type for monads:
class Ref m r | m->r where newRef :: a -> m (r a) readRef :: r a -> m a writeRef :: r a -> a -> m ()
instance Ref IO IORef where ... instance Ref (ST s) (STRef s) where ...
this class allows to write monad-independent code, for example:
doit = do x <- newRef 0 a <- readRef x writeRef x (a+1) readRef x
can be runned in IO or ST monads, or in any monad derived from IO/ST (with appropriate instance Ref definitions). As you can see, even such small example require using FDs. [..]
this will allow to rewrite my Ref class as:
type Ref IO = IORef Ref (ST s) = STRef s
You are going in the right direction, but what you want here are associated types; i.e., you want type functions that are open and can be extended (in the same way as classes can be extended by adding new instances). Your example reads as follows with associated types: class Monad m => RefMonad m where type Ref m :: * -> * newRef :: a -> m (Ref m a) readRef :: Ref m a -> m a writeRef :: Ref m a -> a -> m () instance RefMonad IO where type Ref IO = IORef ... instance RefMonad (ST s) where type Ref (ST s) = STRef s ... My statement remains: Why use a relational notation if you can have a functional one? (The RefMonad class is btw very similar to a functor of ML's module system.[*]) See http://hackage.haskell.org/trac/haskell-prime/wiki/AssociatedTypes for more details on associated types. Manuel [*] Cf http://www.informatik.uni-freiburg.de/~wehr/diplom/