Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Discriminators as first class citizens of sum types#21205

goshacodes started this conversation inFeature Requests
Discussion options

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:

  1. Make this literal constants (if they are literal constants for all of the case children) visible at compile time in any way
  2. If possible - expose this information to mirrors

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:

  1. Enum ordinal is bound to ordinal, consider situation when developer changes order of case chilren (just because he doesn't like it) and deserialization starts failing at runtime

  2. When you write integration with other software systems you often use provided by that system protocol, where discriminators can be strings and not bound in any way to ordinal of case children in your scala model

  3. Case labels have same problem, they are bound to your case class name

You must be logged in to vote

Replies: 1 comment 17 replies

Comment options

  1. If possible - expose this information to mirrors

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 asTuple.Index[MirroredElemTypes, Baz]

You must be logged in to vote
17 replies
@goshacodes
Comment options

Let's try SIP

@bishabosha
Comment options

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?)

@goshacodes
Comment options

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.

@prolativ
Comment options

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 likeFoo[?]

@goshacodes
Comment options

It brings complexity to users, I wouldn't use it myself

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Labels
None yet
3 participants
@goshacodes@prolativ@bishabosha

[8]ページ先頭

©2009-2025 Movatter.jp