A Nullable type for scala3
Nobody has claimed this yet.
- Dominant language
- Scala
- Stars
- 5.5k
- Forks
- 1.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 5
Description
I was using explicit nulls recently in a scala3 only project and had to deal with a java API that returned null. I took a moment to make a small wrapper to use a more FP style:
import scala.quoted.*
opaque type Nullable[+T] = T | Null
object Nullable:
extension [T](inline nullable: Nullable[T])
transparent inline def fold[A](inline ifNull: => A)(inline fn: T => A): A =
${ foldImpl('nullable, 'ifNull, 'fn) }
inline def isNull: Boolean =
fold(true)(_ => false)
inline def nonNull: Boolean =
fold(false)(_ => true)
inline def map[B](inline fn: T => B): Nullable[B] =
fold(null: Null)(fn)
inline def flatMap[B](inline fn: T => Nullable[B]): Nullable[B] =
fold(null: Null)(fn)
inline def toOption: Option[T] =
fold(None)(Some(_))
inline def iterator: Iterator[T] =
fold(Iterator.empty)(Iterator.single(_))
inline def apply[A](inline a: A | Null): Nullable[A] =
a
private def foldImpl[T: Type, A: Type](
nullable: Expr[Nullable[T]],
ifNull: Expr[A],
fn: Expr[T => A]
)(using Quotes): Expr[A] =
'{
val n = $nullable
given CanEqual[T | Null, Null] = CanEqual.derived
if (n == null) $ifNull
else {
val safe: T = n.asInstanceOf[T]
${ Expr.betaReduce('{ $fn(safe) }) }
}
}
I think this type could have lawful implementations of many typeclasses: Monad, Traverse, Foldable, Hash, Order, Eq, Monoid, Group (maybe more algebraic typeclasses).
Should I flesh this out and make a PR to add it to cats.data perhaps? It could be nice to have a zero-cost abstraction for nullable types from Java and javascript interop.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the proposed Nullable definition in the issue and review existing cats.data types and typeclass conventions before deciding whether the abstraction belongs there. Done means a scoped proposal or PR addresses Scala 3 and Java/JavaScript interop, identifies the supported lawful typeclasses, and provides validation for the chosen behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- scala
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100