Skip to content

Instantly share code, notes, and snippets.

@tarao
Last active February 6, 2024 09:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tarao/0f2ff9912cccb0f6636739ff11640567 to your computer and use it in GitHub Desktop.
Save tarao/0f2ff9912cccb0f6636739ff11640567 to your computer and use it in GitHub Desktop.
//> using dep "com.github.tarao::record4s:0.11.2"
import com.github.tarao.record4s.%
import com.github.tarao.record4s.typing.Record.Append
import scala.util.NotGiven as !
type NameField = %{ val name: String }
type AgeField = %{ val age: Int }
type OsField = %{ val os: String }
type ShouldNotHave[R, Field] = ![R <:< Field]
extension [R <: %](p: R) {
def withName[RR <: %](name: String)(using
R ShouldNotHave NameField,
Append.Aux[R, NameField, RR]
): RR = p + name
def withAge[RR <: %](age: Int)(using
R ShouldNotHave AgeField,
Append.Aux[R, AgeField, RR]
): RR = p + age
def withOs[RR <: %](os: String)(using
R ShouldNotHave OsField,
Append.Aux[R, OsField, RR]
): RR = p + os
}
val e = %()
val fulfilled = e.withName("windymelt").withAge(30).withOs("openSUSE")
fulfilled.name
fulfilled.age
fulfilled.os
//> using dep "com.github.tarao::record4s:0.11.2"
import com.github.tarao.record4s.%
import com.github.tarao.record4s.typing.Record.Concat
import scala.util.NotGiven as !
type NameField = %{ val name: String }
type AgeField = %{ val age: Int }
type OsField = %{ val os: String }
type ShouldNotHave[R, Field] = ![R <:< Field]
type ++[R1, R2] = Concat[R1, R2]
type :=[Out0 <: %, A] =
A match {
case Concat[r1, r2] =>
Concat[r1, r2] { type Out = Out0 }
}
extension [R <: %](p: R) {
def withName[RR <: %](name: String)(using
R ShouldNotHave NameField,
RR := R ++ NameField,
): RR = p + name
def withAge[RR <: %](age: Int)(using
R ShouldNotHave AgeField,
RR := R ++ AgeField,
): RR = p + age
def withOs[RR <: %](os: String)(using
R ShouldNotHave OsField,
RR := R ++ OsField,
): RR = p + os
}
val e = %()
val fulfilled = e.withName("windymelt").withAge(30).withOs("openSUSE")
fulfilled.name
fulfilled.age
fulfilled.os
@tarao
Copy link
Author

tarao commented Feb 5, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment