
On Thu, Jul 21, 2011 at 6:46 PM, Simon Peyton-Jones
You point is that the (C Int) dictionary has (C String) as a superclass, and (C String) has (C Int) as a superclass. So the two instances are mutually recursive, but that’s ok.
That is not unreasonable. But it is dangerous. Consider
class C [a] => C a
Then any dictionary for (C a) would contain a dictionary for (C [a]) which would contain a dictionary for C [[a]], and so on. Haskell is lazy so we might even be able to build this infinite dictionary, but it *is* infinite.
It’s a bit like the “recursive instance” stuff introduced in “Scrap your boilerplate with class”.
After 5 mins thought I can’t see a reason why this could not be made to work. But it’d take work to do. If you have a compelling application maybe you can open a feature request ticket, describing it, and referring this thread?
Has anyone else come across this?
Yes. I wanted to write typeclasses for data which can be converted between mutable and immutable forms like this: (from memory and simplified a bit, so not entirely correct in other respects) class Immutable (Frozen a) => Mutable a where type Frozen a unsafeFreeze :: a -> Frozen a makeCopy :: a -> IO a class Mutable (Thawed a) => Immutable a where type Thawed a unsafeThaw :: a -> Thawed a As this causes a superclass cycle, I had to go with a MPTC instead. Not any less capable, but not as nice looking. Actually, I had wanted to write: class (Immutable (Frozen a), Thawed (Frozen a) ~ a) => Mutable a where ... and vice versa So I was depending on multiple as-yet unimplemented features. This is different from the original example - I don't know if cyclic equality superclass contexts would be sensible and-or implementible?
Simon
From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell-users-bounces@haskell.org] On Behalf Of Ryan Trinkle Sent: 20 July 2011 17:37 To: glasgow-haskell-users@haskell.org Subject: Superclass Cycle via Associated Type
The following code doesn't compile, but it seems sensible enough to me. Is this a limitation of GHC or is there something I'm missing?
class C (A x) => C x where
type A x :: *
instance C Int where
type A Int = String
instance C String where
type A String = Int
The error I get is:
SuperclassCycle.hs:1:1:
Cycle in class declarations (via superclasses):
SuperclassCycle.hs:(1,1)-(2,15): class C (A x) => C x where {
type family A x :: *; }
Ryan
_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
-- Work is punishment for failing to procrastinate effectively.