[Haskell-cafe] Monad transformers, design
tonymorris at gmail.com
Sat Jul 31 08:56:31 EDT 2010
Hello I have a question regarding monad transformers and how to design
an API with a transformer. I have a narrowed code example of the
question. Please see the questions in the comments below.
-- Suppose some data type
newtype Inter a = Inter (Int -> a)
-- and a monad transformer for that data type.
newtype InterT m a = InterT (m (Inter a))
-- It's easy to implement this type-class
instance (Monoid a) => Monoid (Inter a) where
mempty = Inter (const mempty)
Inter a `mappend` Inter b = Inter (a `mappend` b)
-- and for the transformer too by lifting into the monad
instance (Monad m, Monoid a) => Monoid (InterT m a) where
mempty = InterT (return mempty)
InterT a `mappend` InterT b = InterT (liftM2 mappend a b)
-- But what about this type-class?
class Ints a where
ints :: a -> Int -> Int
-- Seems easy enough
instance (Integral a) => Ints (Inter a) where
ints (Inter a) n = fromIntegral (a n)
-- OH NO!
instance (Monad m, Integral a) => Ints (InterT m a) where
ints (InterT a) n = error "OH NO!"
-- We could try this
class Copointed f where
copoint :: f a -> a
-- but it seems rather impractical
instance (Copointed m, Integral a) => Ints (InterT m a) where
ints (InterT a) = ints (copoint a)
So it seems that for some type-classes it is possible to implement
for both the data type and the transformer, but not all type-classes.
Is there a general approach to this problem?
More information about the Haskell-Cafe