
I am unsure how to change the name of a class in a library whilst providing a safe deprecation cycle for the users of the library. Suppose I have version 1 of my library with a class -- Version 1 class Foo a where foo :: a and I want to migrate it to version 3 as follows, but with a deprecation cycle provided by version 2 that allows code to work with either version 1 and 2, or 2 and 3. -- Version 3 class Bar a where bar :: a Then I can try to write version 2 as -- Version 2 {-# ConstraintKinds #-} class Foo a where bar :: a bar = foo foo :: a foo = bar type Bar = Foo This satisfies the following conditions: Users of versions 1 and 2 can use * The constraint Foo * The method foo * The class Foo and method foo for implementing their own instances User of versions 2 and 3 can use * The constraint Bar * The method bar * The method bar for implementing their own instances but they cannot jointly use * The *class* Bar for implementing their own instances (since Bar is not a class, just a Constraint) Is there any way I can write a version 2 that allows users to implement instances that work with both version 2 and version 3? Thanks, Tom

Tom Ellis
I am unsure how to change the name of a class in a library whilst providing a safe deprecation cycle for the users of the library. Suppose I have version 1 of my library with a class
-- Version 1 class Foo a where foo :: a
and I want to migrate it to version 3 as follows, but with a deprecation cycle provided by version 2 that allows code to work with either version 1 and 2, or 2 and 3.
-- Version 3 class Bar a where bar :: a
What if you inserted Bar as a superclass of Foo in V2? -- Version 1 class Foo a where foo :: a -- Version 2 {-# DEPRECATED Foo "it's going away in V3" #-} class Bar a => Foo a where foo :: a class Bar a where bar :: a -- Version 3 class Bar a where bar :: a Users of version 1 can use Foo/foo/... When they upgrade to version 2, they get forced to write a Bar instance, get warned that Foo is going away, and they can use the class Bar to implement their own instances. Users of version 3 can only use Bar/bar/... Does that help? -- Jack

On Sun, Jun 16, 2019 at 09:59:27AM +1000, Jack Kelly wrote:
Tom Ellis
writes: I am unsure how to change the name of a class in a library whilst providing a safe deprecation cycle for the users of the library. Suppose I have version 1 of my library with a class
-- Version 1 class Foo a where foo :: a
and I want to migrate it to version 3 as follows, but with a deprecation cycle provided by version 2 that allows code to work with either version 1 and 2, or 2 and 3.
-- Version 3 class Bar a where bar :: a
What if you inserted Bar as a superclass of Foo in V2?
-- Version 1 class Foo a where foo :: a
-- Version 2 {-# DEPRECATED Foo "it's going away in V3" #-} class Bar a => Foo a where foo :: a
class Bar a where bar :: a
-- Version 3 class Bar a where bar :: a
Users of version 1 can use Foo/foo/...
When they upgrade to version 2, they get forced to write a Bar instance, get warned that Foo is going away, and they can use the class Bar to implement their own instances.
Unfortunately I don't think this scheme allows the user to write code that is compatible with version 1 and version 2 at the same time.

On Jun 15, 2019, at 12:20 PM, Tom Ellis
wrote: I am unsure how to change the name of a class in a library whilst providing a safe deprecation cycle for the users of the library. Suppose I have version 1 of my library with a class
Is this perhaps essentially: https://gitlab.haskell.org/ghc/ghc/issues/7543 -- Viktor.

On Sat, Jun 15, 2019 at 11:51:33PM -0400, Viktor Dukhovni wrote:
On Jun 15, 2019, at 12:20 PM, Tom Ellis
wrote: I am unsure how to change the name of a class in a library whilst providing a safe deprecation cycle for the users of the library. Suppose I have version 1 of my library with a class
Is this perhaps essentially:
It's closely related and indeed option 2 that Edward Yang proposes below would allow me to do what I want: "Allow instance declarations on constraint synonyms, but only if after desugaring the synonym, you end up with a single class head." https://gitlab.haskell.org/ghc/ghc/issues/13267

On Sun, Jun 16, 2019 at 08:02:20AM +0100, Tom Ellis wrote:
On Sat, Jun 15, 2019 at 11:51:33PM -0400, Viktor Dukhovni wrote:
On Jun 15, 2019, at 12:20 PM, Tom Ellis
wrote: I am unsure how to change the name of a class in a library whilst providing a safe deprecation cycle for the users of the library. Suppose I have version 1 of my library with a class
Is this perhaps essentially:
It's closely related and indeed option 2 that Edward Yang proposes below would allow me to do what I want:
"Allow instance declarations on constraint synonyms, but only if after desugaring the synonym, you end up with a single class head."
Your motivation sounds quite reasonable, though the issues appear to be difficult, maybe if you ask again there'll be a different answer this time? -- Viktor.
participants (3)
-
Jack Kelly
-
Tom Ellis
-
Viktor Dukhovni