sager icon indicating copy to clipboard operation
sager copied to clipboard

Generic records for Scala

Sager

Release Version Snapshot Version Build Status

Generic records for Scala. Record types have the form

Field[Label1, Value1] with ... with Field[LabelN, ValueN]

where Field is invariant in its first argument and covariant in the second.

Using Sager in your project

Add Sager to your dependencies

libraryDependencies += "com.github.mvv.sager" %% "sager" % "0.2-M1"

To construct a record, use

import com.github.mvv.sager._
// Label types
trait Foo
trait Bar
trait Baz
val r = Field[Foo]("foo").add[Bar](123).add[Baz](Vector.empty[Double])
// val r: Field[Foo,String] with Field[Bar,Int] with Field[Baz,Vector[Double]]

Record types are polymorthic in expected ways:

// All of the following implicit searches succeed
implicitly[r.type <:< Field[Bar,Int] with Field[Foo,String]]
implicitly[r.type <:< Field[Baz,Seq[Double]]]

Accessing and modifying fields is simple:

val bar = r.get[Bar]
// val bar: Int = 123
val newBar = r.add[Bar](false).get[Bar]
// val newBar: Boolean = false
// You can omit the `: Int` annotation in Scala 3
val updatedBar = r.update[Bar]((_: Int) > 100).get[Bar]
// val updatedBar: Boolean = true
// Same thing, but more inference-friendly
val mappedBar = r.field[Bar].map(_ > 100).get[Bar]
// val mappedBar: Boolean = true
val r1 = r.remove[Bar]
// val r1: Field[Foo,String] with Field[Baz,Vector[Double]]

Submodules

  • sager-zio contains helpers for using records as ZIO environments
  • sager-zio-interop-cats extends ZIO Cats-Effect interop with sager-zio support