- Notifications
You must be signed in to change notification settings - Fork1.1k
Discriminators as first class citizens of sum types#21205
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
Consider following AST: enumFoo(valdiscriminator:String):caseBar()extendsFoo("bar")caseBaz()extendsFoo("baz") "bar" and "baz" are literal constants, but now they are not exposed at compile time in any way. So to make derivation of JsonReader (for example) possible I need to stub all case children instances and get this field. I propose to:
So generation of this code could be possible without dirty hacks givenbarJsonReader:JsonReader[Bar]=???givenbazJsonReader:JsonReader[Baz]=???valdiscriminator=???discriminatormatchcase"bar"=> barJsonReadercase"baz"=> bazJsonReader Why not use ordinal or MirroredElemLabels:
|
BetaWas this translation helpful?Give feedback.
All reactions
Replies: 1 comment 17 replies
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
-
The ordinal of an enum case is compile time information - its the index of the type in the MirroredElemTypes in the Mirror - which you can compute manually, or its the same as |
BetaWas this translation helpful?Give feedback.
All reactions
-
Let's try SIP |
BetaWas this translation helpful?Give feedback.
All reactions
-
Just coming back to this - why would the enum case name not be appropriate? just because its inconvenient to be lower case? ( i.e. why would the selector be different than the case name?) |
BetaWas this translation helpful?Give feedback.
All reactions
-
Yes, you may end up making it snake_case or kebab-case with backticks just because in other contexts someone use it like this. And backticks are not very convenient to use, but thats not all. I was grown in a paradigm where you shouldn't use a class name, because this may break compatibility when any class name change and developers may change names just because they want to. Or it maybe not just basic type, the discriminator can be enum itself or something else with provided typeclass instance for it. Would be great to have a way to get those values compile time in macro. Currently it is not possible - you need an instance to get those. enumFoo(valdiscriminator:String):caseBar()extendsFoo("bar")caseBaz()extendsFoo("baz") Maybe it is not a big problem, but one day I thought it could be useful. |
BetaWas this translation helpful?Give feedback.
All reactions
-
How about using singleton type parameters as a workaround in this case? E.g. enumFoo[D<:String&Singleton]:caseBar()extendsFoo["bar"]caseBaz()extendsFoo["baz"]inlinedefdiscriminator:D= compiletime.constValue[D]objectFoo:inlinedefcaseDiscriminator[F<:Foo[?]]:String=inline compiletime.erasedValue[F]matchcase_:Foo[d]=> compiletime.constValue[d]@maindefrun()= println(Foo.Bar().discriminator) println(Foo.caseDiscriminator[Foo.Bar]) Unfortunately I didn't manage to make this work with type members, which would save us from writing things like |
BetaWas this translation helpful?Give feedback.
All reactions
-
It brings complexity to users, I wouldn't use it myself |
BetaWas this translation helpful?Give feedback.