RE: [Haskell] Deferred instance declarations (serialization ofexistential boxes)

[redirecting to GHC users, since it's a GHC-specific question] Misha | I asked this question on haskell-cafe once, but my post didn't get any | responses, so I try once again here explaining a bit more where my | problem comes from. I was at ICFP. | Suppose I have a monomorphic datatype, say T and want to do something | with it, which depends on an instance of class C being defined for T. | However I can only provide this instance later, in a different module. | So I would like to write something like | | > f :: C T => T -> T | or | > instance C T => C T' where | > -- a body that uses functions from C T There is no reason in principle why this isn't ok. But there is a practical reason why things are the way they are. Generally, GHC tries to share constraints as much as possible, so that a (C T) constraint in one function right hand side is satisfied by the same binding as another (C T) constraint from another right hand side. So in general, GHC "floats" constraints outwards if they don't mention any type variables bound by the forall's of the type signature. The whole question of the interaction of type signatures and constraints is quite delicate, and I rather doubt I'll change this behaviour soon. (And no one else has asked for it before, I think.) But I think the case is stronger for top-level constraints, and I will bear it in mind. If you would like to open a Trac feature request, please do so. Concerning your application | I am having a box like | > data Box = forall a. Cxt a => Box a | and want to write a Read instances for it. I don’t see how it helps to defer the Read instance. Reading existentials is bound to be difficult, or even impossible. I guess it depends what is in Cxt. Simon

Simon Peyton-Jones wrote:
Concerning your application
| I am having a box like | > data Box = forall a. Cxt a => Box a | and want to write a Read instances for it.
I don’t see how it helps to defer the Read instance.
I would defer the instance declaration till the point where I know all types that will ever go into the box (for instance in my Main module). The Show instance of Box would write the representation of a together with it's type (this means Cxt should contain at least Show and Typeable). The Read instance will then contain something like ======================================================== String aType <- lexP result <- case aType of "[Int]" -> (readPrec :: ReadPrec [Int]) >>= (return . Box) "SomeOtherType" -> (readPrec :: ReadPrec SomeOtherType) >>= (return . Box) -- <more of such cases> _ -> error (aType ++ " cannot be read inside of Box") ======================================================== Not very elegant of course, but it seems to be the only way to Read existentials.
But I think the case is stronger for top-level constraints, and I will bear it in mind. If you would like to open a Trac feature request, please do so.
Ok, I will. Cheers, Misha

Misha I'm happy to tell you that your wish has been granted. I was able to implement the change you wanted (you called it deferred instance declarations) as part of an overhaul of the type-class machinery in GHC. I'll send out a more detailed message about this to ghc-users. Simon | -----Original Message----- | From: glasgow-haskell-users-bounces@haskell.org [mailto:glasgow-haskell-users-bounces@haskell.org] | On Behalf Of Misha Aizatulin | Sent: 27 September 2006 21:08 | To: GHC Users Mailing List | Subject: Re: [Haskell] Deferred instance declarations (serialization of existential boxes) | | Simon Peyton-Jones wrote: | > Concerning your application | > | > | I am having a box like | > | > data Box = forall a. Cxt a => Box a | > | and want to write a Read instances for it. | > | > I don’t see how it helps to defer the Read instance. | | I would defer the instance declaration till the point where I know all | types that will ever go into the box (for instance in my Main module). | The Show instance of Box would write the representation of a together | with it's type (this means Cxt should contain at least Show and | Typeable). The Read instance will then contain something like | | ======================================================== | String aType <- lexP | | result <- case aType of | "[Int]" -> | (readPrec :: ReadPrec [Int]) >>= (return . Box) | "SomeOtherType" -> | (readPrec :: ReadPrec SomeOtherType) >>= (return . Box) | | -- <more of such cases> | | _ -> error (aType ++ " cannot be read inside of Box") | ======================================================== | | Not very elegant of course, but it seems to be the only way to Read | existentials. | | > But I think the case is stronger for top-level constraints, and I will bear it in mind. | > If you would like to open a Trac feature request, please do so. | | Ok, I will. | | Cheers, | Misha | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users
participants (2)
-
Misha Aizatulin
-
Simon Peyton-Jones