2

In typescript it looks like this

type Option<T> = {some: T} | 'none'
type Optional<T> = {
  [P in keyof T]: Option<T[P]>
};
type Foo = {x: string, y: number}
type OptionalFoo = Optional<Foo>
const foo: OptionalFoo = {x: 'none', y : {some: 123}}
case class Foo(x: String, y: Int)

I would like to have

type OptionalFoo = Optional[Foo] == case class OptionalFoo(x: Option[String], y: Option[Int])

Is it possible to achive something like this in Scala 3?

user
  • 7,435
  • 3
  • 14
  • 44
ais
  • 2,514
  • 2
  • 17
  • 24
  • As far as I know, not when you have a variable number of fields. – user Jan 20 '21 at 14:12
  • [Here](https://stackoverflow.com/q/62248481/11882002) is a similar question, but I doubt you'll find anything there. You may just have to write a compiler plugin yourself, or find a workaround, unfortunately. – user Jan 20 '21 at 15:52

1 Answers1

1

If you do not care about the names of each field, you could perhaps do this:

type Foo = (String, Int)
type Optional[T <: Tuple] = Tuple.Map[T, Option]
type OptionalFoo = Optional[Foo]

val optionalFoo: OptionalFoo = (Some("foobar"), None)
optionalFoo match {
  case (x, y) => println(s"x is $x, y is $y")
}

Scastie

This may have been possible in Scala 2, which supported annotation macros. Perhaps type class derivation may also help you here. Shapeless also has many useful mechanisms if you do not care about actually creating a completely new case class.

user
  • 7,435
  • 3
  • 14
  • 44
  • Thanks. Could It be implemented for `type Foo = (("x", String),("y", Int))`? Is it possible to convert case class to such tuples in Scala 3? – ais Jan 21 '21 at 06:11
  • @ais Convert a case class to a tuple? Shapeless can probably do that. But I thought you wanted to make a case class *from* a tuple. Have I misinterpreted your question? – user Jan 21 '21 at 14:02
  • I thought maybe such scenario could be possible `case class Foo(x: String, x: Int)` convert to tuple `type Foo = (("x", String),("y", Int))` and tranform tuple with `Optional[Foo] == (("x", Option[String]),("y", Option[Int]))` and use such tuple as some sort of case class alternative. – ais Jan 21 '21 at 16:18
  • @ais You can directly turn the tuple version of `Foo` into the tuple of tuples. Give me a minute – user Jan 21 '21 at 16:22