I'm not sure when this "feature" was added, but I'm pretty sure that my 
original implementation of associated types was exactly what you describe in 
the solution. Or did I miss anything?

I think you are right. I think I added the new stuff in a fit of enthusiasm one 
day, a fit that I am now regretting!   But I'm just checking that no one has 
meanwhile become addicted to it.

Simon

From: Manuel Chakravarty [mailto:mchakrava...@me.com]
Sent: 24 June 2014 08:54
To: Simon Peyton Jones
Cc: GHC List; ghc-d...@haskell.org
Subject: Re: Associated type instances

Simon,

I'm not sure when this "feature" was added, but I'm pretty sure that my 
original implementation of associated types was exactly what you describe in 
the solution. Or did I miss anything?

Manuel

Simon Peyton Jones <simo...@microsoft.com<mailto:simo...@microsoft.com>>:
Friends
I want to make withdraw (or, rather, simplify) a little-known feature in GHC, 
but before I do so I want to check that no one is going to have a heart attack.
Relevant bits of the user manual: 
http://www.haskell.org/ghc/docs/latest/html/users_guide/type-families.html#assoc-decl
All of this arose when thinking about fixing Trac #9063.
I believe that this change will affect essentially nobody, and I propose to 
implement forthwith in HEAD (and hence 7.10).
Does anyone object?
Thanks
Simon

The issue
Consider this:
class C a where
   type T a b :: *

instance C [x] where
   type T [x] b = x -> b
That is just what you'd expect.  But currently this is allowed too:
instance C [x] where
   type T [x] Int = x -> Int
   type T [x] Bool = Bool -> x
That is, GHC 7.8 allows many associated type instances, provided they don't 
overlap.  But, oddly you can't further instantiate the instance pattern. This 
would make just as much sense, but isn't allowed:
instance C [x] where
   type T [Int] b = b -> Int
   type T [Bool] b = Bool -> b
Moreover, as the user manual says, for an open kind like *, none of this really 
makes sense. It really only makes sense for a closed kind. Something like
class D a where
   type S (b :: Bool) a :: *
Now this would make some kind of sense:
instance D [x] where
   type S True [x] = x -> x
   type S False [x] = x
But for closed kinds, you really want a closed type family.  So this would be 
better:
instance D [x] where
   type S b [x] = SHelp x b

type family SHelp x b where
  SHelp x True = x -> x
  SHelp x False = x

So yes, you do have to declare a named helper type, but you get something much 
more perspicuous and explicit in exchange.
All of this also applies to the default declaration(s) which you can supply for 
an associated type (see 7.7.3.2 in the link above), only it's a bit more 
complicated and indirect.
My solution
I propose to simplify substantially, as follows:

*         The "shared arguments" of an associated type are the argument 
positions that mention a type variable from the class header.  So in class C 
above, the first argument position of T is "shared"; and in class D, the second 
argument position of S is shared.

*         A instance for an associated type (in a class instance declaration) 
cf 7.7.3.1 must have

o   type variables in the non-shared argument positions, and

o   an exact copy of the corresponding instance header type in the shared 
positions

*         For each associated type you can have

o   at most one default declaration in the class declaration

o   at most one type instance declaration in the class instance declaration


_______________________________________________
ghc-devs mailing list
ghc-d...@haskell.org<mailto:ghc-d...@haskell.org>
http://www.haskell.org/mailman/listinfo/ghc-devs

_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to