Skip to content

Instantly share code, notes, and snippets.

@monadplus
Created March 2, 2019 21:28
Show Gist options
  • Save monadplus/c1bd90e34ae11d0ee123d6956f79c4c8 to your computer and use it in GitHub Desktop.
Save monadplus/c1bd90e34ae11d0ee123d6956f79c4c8 to your computer and use it in GitHub Desktop.
Safe List using GADT
/*
{-#LANGUAGE GADTs, EmptyDataDecls #-}
-- (the EmptyDataDecls pragma must also appear at the very top of the module,
-- in order to allow the Empty and NonEmpty datatype declarations.)
data Empty
data NonEmpty
data SafeList a b where
Nil :: SafeList a Empty
Cons:: a -> SafeList a b -> SafeList a NonEmpty
safeHead :: SafeList a NonEmpty -> a
safeHead (Cons x _) = x
*/
type INothing <: Nothing
trait Empty
trait NonEmpty
trait SafeList[+A, -B]
case object Nil extends SafeList[INothing, Empty]
case class Cons[A, B](a: A, as: SafeList[A, B]) extends SafeList[A, NonEmpty]
def safeHead[A](as: SafeList[A, NonEmpty]): A =
as match {
case Cons(a, _) => a
}
val empty = Nil
val xs = Cons(true, empty)
safeHead(empty) // type mismatch
safeHead(xs) // res0: Int = 10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment