Dne 06/03/2013 09:11 PM, Henning Thielemann napsal(a):
On Mon, 3 Jun 2013, Edward Kmett wrote:
The first option is
class Monad m => MonadRef r m | m -> r where
newRef :: a -> m (r a)
...
This has the benefit of using quite portable extensions.
The second option is
class Monad m => MonadRef m where type Ref m :: * -> *
newRef :: a -> m (Ref m a)
This takes us into GHC specific territory, by using type families, but avoids polluting every type that uses
one with an extra 'ref' param. I use this variant in my as-yet-unreleased 'revisions' package.
Both of these have the benefit that they can work with transformers, but they carry the limitation that you
can't have multiple reference types for the same monad. e.g. you can't use the same combinators for both
IORefs and, say, MVars or TVars within the same monad. This is arguably not so much a problem as they have
very different operational semantics!
I thought the functional dependency should be the other way round: From the reference type to the monad where it lives in.
For monads, it's (AFAIK) always this way, because
m
is always in the result, but not necessarily the other type. Let's considerreadRef :: r a -> m a
In order to type-check
x
inreadRef x
, we need to determiner a
fromm a
, so the dependency must bem -> r
.
_______________________________________________
Libraries mailing list
Libraries@haskell.org
http://www.haskell.org/mailman/listinfo/libraries