mvv / sager   0.2-M1


Generic records for Scala


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]]


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