Skip to content

Instantly share code, notes, and snippets.

@calvinlfer
Created June 11, 2021 20:25
Show Gist options
  • Save calvinlfer/f6d734659944e28bff90553b4f4390f1 to your computer and use it in GitHub Desktop.
Save calvinlfer/f6d734659944e28bff90553b4f4390f1 to your computer and use it in GitHub Desktop.
Refined types in Scala 3 with ZIO Prelude
import scala.compiletime._
import zio.prelude._
package safer:
type Digit5OrMore = Digit5OrMore.Type
object Digit5OrMore extends Subtype[Int]:
private inline def check(i: Int): Boolean = i >= 5
private inline def renderError(i: Int): String = s"input $i must be at least 5"
inline def compiletime(inline i: Int): Digit5OrMore =
inline if check(i) then Digit5OrMore(i)
else error(renderError(i))
def runtime(i: Int): Either[String, Digit5OrMore] =
if check(i) then Right(Digit5OrMore(i))
else Left(renderError(i))
val compileTimeExample: Digit5OrMore = Digit5OrMore.compiletime(4) // compile time error
val runtimeExample: Either[String, Digit5OrMore] = Digit5OrMore.runtime(4). // Left("input 4 must be at least 5")
@calvinlfer
Copy link
Author

calvinlfer commented Jun 11, 2021

Since opaque types have a limitation where they cannot be used with inline as of Scala 3.0.0, we make use of Newtype/Subtype

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