Skip to content
master
Go to file
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
src
 
 
 
 
 
 
 
 

README.md

scala-adt

Haskell-style Algebraic Data Types for Scala

Usage

Scala supports ADTs by using sealed traits and case classes and objects. For instance, if we wanted to implement a Maybe type, we could do something like the following -

sealed trait Maybe[+A]
final case class Just[+A](a: A) extends Maybe[A]
case object Nix extends Maybe[Nothing]

This can get pretty verbose, especially when there are more constructors.

In Haskell, we can define an ADT using the following syntax -

data Maybe a = Just a | Nix

Thanks to the @ADT macro, we can get pretty close to the Haskell syntax -

@ADT trait Maybe[A] { Just(a: A); Nix }

This will generate code semantically equivalent to the following -

sealed trait Maybe[+A]
object Maybe {
  final case class Just[+A](a: A) extends Maybe[A]
  case object Nix extends Maybe[Nothing]
  
  object ctors {
    val Just = Maybe.Just
    val Nix = Maybe.Nix
  }
}

You can then use your new ADT just as you'd expect. You can add methods to the trait or companion object as needed. Constructors are inferred as the first statements defined in the trait.

@ADT trait Maybe[A] {
  Just(a: A)
  Nix

  def map[B](f: A => B): Maybe[B] = this match {
    case Just(x) => Just(f(x))
    case Nix => Nix
  }
}

object Maybe {
  def apply[A](a: A): Maybe[A] = {
    if (a == null) Nix else Just(a)
  }
}

// Optional, used to import constructors to avoid always qualifying them.
import Maybe.ctors._

object Example {
  def run() = {
    val m1 = Maybe(1)
    println(m1.map(_ + 2))
    // prints "Just(3)"

    val m2: Maybe[Int] = Nix
    m2 match {
      case Just(_) => println(s"Found $x")
      case Nix => println("Not found")
    }
    // prints "Not found"
  }
}

About

Haskell-style Algebraic Data Types for Scala

Resources

Releases

No releases published

Packages

No packages published

Languages

You can’t perform that action at this time.