Having just started to dip my toes with Scala and am now looking to understand whether there is any way to express Deep partial types (recursive types) in Scala?
###################### Update ######################
What I am trying to achieve is to take an existing case class and somehow "Version" it, such that it recursively adds that to every field even at deeply nested levels
e.g. lets assume I have these classes defined
case class A(p1: Int, p2: Int, ..)
case class B(p1: Map[String, A])
case class C(param1: String, param2: String, param3: Option[B])
I want to version C, which means for every parameter type (recursively) I want an optional version: Int to be added.
The naive way, I see, would be to define a new class VersionedValue and then manually redefine all of the existing types to accommodate this.
e.g. what it may look like
case class VersionedValue [A](value: A, version: Option[Int])
case class A(p1: VersionedValue[Int], p2: VersionedValue[Int])
case class B(p1: Map[String, VersionedValue[A]])
case class C(p1: VersionedValue[String],
p2: VersionedValue[String],
p3: Option[B])
####################################################
Having worked with TypeScript for a while, that usually would look something like this:
/**
* the VersionedDeepPartial<T> will recursively iterate through
* each of the "keys" (or attributes) and for each creates a new
* object that adds a version field. The value attribute will hold
* what was originally the type for the key.
*/
export type VersionedDeepPartial<T> = {
[P in keyof T]?: {value: VersionedDeepPartial<T[P]>; version?:number}
};
// So if I had an interface (in typescript) looking like:
interface A {
p1: number,
p2: number,
}
interface B {
[key: string]: A
}
interface C {
p1: String,
p2: String,
p3: B
}
/**
* Note that interface C does not define any versioning attribute to
* its fields. But by wrapping the type within the
*/
VersionedDeepPartial<T>
const partialFoo: VersionedDeepPartial<C> = {
p1: { value: "asdf", version: 1 },
p2: { value: "asdf" },
p3: {
"somekey": {
p1: {value: 1, version: 1},
p2: {value: 2}
}
}
Basically, what I want is to define a new type by recursing through an existing type/class definition and "injecting" versioning to it.
I've read/browsed around for explanations on this topic with no success. Is this possible to express in Scala?