Skip to content

Instantly share code, notes, and snippets.

@juanjovazquez
Created March 21, 2020 19:21
Show Gist options
  • Save juanjovazquez/2e24f5ceedafee01e83473f77939a43a to your computer and use it in GitHub Desktop.
Save juanjovazquez/2e24f5ceedafee01e83473f77939a43a to your computer and use it in GitHub Desktop.
// For educational purposes
object MyListModule {
trait MyList[+A]
object MyList {
case object Empty extends MyList[Nothing]
case class Cons[A](h: A, t: MyList[A]) extends MyList[A]
def head[A](l: MyList[A]): A =
l match {
case Empty => sys.error("head of empty list")
case Cons(h, _) => h
}
def headOption[A](l: MyList[A]): Option[A] =
l match {
case Empty => None
case Cons(h, _) => Some(h)
}
def tail[A](l: MyList[A]): MyList[A] =
l match {
case Empty => Empty
case Cons(_, t) => t
}
def length[A](l: MyList[A]): Int =
l match {
case Empty => 0
case Cons(_, t) => 1 + length(t)
}
def prepend[A](x: A, l: MyList[A]): MyList[A] =
l match {
case Empty => Cons(x, Empty)
case Cons(h, t) => Cons(x, l)
}
def append[A](x: A, l: MyList[A]): MyList[A] =
l match {
case Empty => Cons(x, Empty)
case Cons(h, t) => Cons(h, append(x, t))
}
def concat[A](l1: MyList[A], l2: MyList[A]): MyList[A] =
l1 match {
case Empty => l2
case Cons(h, t) => Cons(h, concat(t, l2))
}
def map[A, B](l: MyList[A])(f: A => B): MyList[B] =
l match {
case Empty => Empty
case Cons(h, t) => Cons(f(h), map(t)(f))
}
implicit class MyListIntOps[A](l: MyList[A]) {
def head: A = MyList.head(l)
def headOption: Option[A] = MyList.headOption(l)
def tail: MyList[A] = MyList.tail(l)
def length: Int = MyList.length(l)
def prepend(x: A): MyList[A] = MyList.prepend(x, l)
def append(x: A): MyList[A] = MyList.append(x, l)
def concat(l2: MyList[A]): MyList[A] = MyList.concat(l, l2)
def map[B](f: A => B): MyList[B] = MyList.map(l)(f)
}
}
}
import MyListModule._
import MyList._
object Main extends App {
val l0 = Empty
val l1 = Cons(1, Empty)
val l2 = Cons(2, l1)
val l3 = Cons(3, l2)
val l4 = l3.prepend(4)
val l5 = l4.append(0)
val l6 = l4.concat(l5)
val l7 = l5.map(_ * 2)
val l8 = l5.map(_ * 2.5)
val lenl2 = l2.length
val lenl3 = l3.length
val hl3 = l3.headOption
val tl3 = l3.tail
println(s"l0: $l0")
println(s"l1: $l1")
println(s"l2: $l2")
println(s"lenl2: $lenl2")
println(s"lenl3: $lenl3")
println(s"hl3: $hl3")
println(s"tl3: $tl3")
println(s"l4: $l4")
println(s"l5: $l5")
println(s"l6: $l6")
println(s"l7: $l7")
println(s"l8: $l8")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment