From 618c9599563fd76d1ddeae32a1c0870764fc036e Mon Sep 17 00:00:00 2001
From: Manos Koukoutos <emmanouil.koukoutos@epfl.ch>
Date: Mon, 20 Jul 2015 01:47:04 +0200
Subject: [PATCH] Unapply in docs, List. List.headOption

---
 doc/purescala.rst                 | 36 ++++++++++++++++++++++---------
 library/collection/List.scala     | 14 ++++++++++++
 library/lang/string/package.scala |  2 +-
 3 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/doc/purescala.rst b/doc/purescala.rst
index bde72673c..f26a5e228 100644
--- a/doc/purescala.rst
+++ b/doc/purescala.rst
@@ -182,16 +182,32 @@ Pattern matching
 .. code-block:: scala
 
  expr match {
-    // Simple (nested) patterns:
-    case CaseClass( .. , .. , ..) => ...
-    case v @ CaseClass( .. , .. , ..) => ...
-    case v : CaseClass => ...
-    case (t1, t2) => ...
-    case 42 => ...
-    case _ => ...
-
-    // can also be guarded, e.g.
-    case CaseClass(a, b, c) if a > b => ...
+   // Simple (nested) patterns:
+   case CaseClass( .. , .. , ..) => ...
+   case v @ CaseClass( .. , .. , ..) => ...
+   case v : CaseClass => ...
+   case (t1, t2) => ...
+   case 42 => ...
+   case _ => ...
+
+   // can also be guarded, e.g.
+   case CaseClass(a, b, c) if a > b => ...
+ }
+
+Custom pattern matching with ``unapply`` methods are also supported:
+
+.. code-block:: scala
+
+ object :: {
+   def unapply[A](l: List[A]): Option[(A, List[A])] = l match {
+     case Nil() => None()
+     case Cons(x, xs) => Some((x, xs))
+   }
+ }
+  
+ def empty[A](l: List[A]) = l match {
+   case x :: xs => false
+   case Nil() => true
  }
 
 Values
diff --git a/library/collection/List.scala b/library/collection/List.scala
index c7a38dc63..b3078c600 100644
--- a/library/collection/List.scala
+++ b/library/collection/List.scala
@@ -35,6 +35,11 @@ sealed abstract class List[T] {
     (that != Nil[T]() || res == this)
   }
 
+  def headOption: Option[T] = this match {
+    case Nil() => None[T]()
+    case Cons(h, _) => Some(h)
+  }
+
   def head: T = {
     require(this != Nil[T]())
     val Cons(h, _) = this
@@ -537,6 +542,15 @@ object ListOps {
 case class Cons[T](h: T, t: List[T]) extends List[T]
 case class Nil[T]() extends List[T]
 
+// 'Cons' Extractor
+object :: {
+  def unapply[A](l: List[A]): Option[(A, List[A])] = l match {
+    case Nil() => None()
+    case Cons(x, xs) => Some((x, xs))
+  }
+}
+
+
 @library
 object ListSpecs {
   def snocIndex[T](l : List[T], t : T, i : BigInt) : Boolean = {
diff --git a/library/lang/string/package.scala b/library/lang/string/package.scala
index f09af7c6e..e3cd3d7ae 100644
--- a/library/lang/string/package.scala
+++ b/library/lang/string/package.scala
@@ -16,7 +16,7 @@ package object string {
 
   @ignore
   def listToList[A](s: ScalaList[A]): List[A] = s match {
-    case h :: t =>
+    case scala.::(h, t) =>
       Cons(h, listToList(t))
     case _ =>
       Nil[A]()
-- 
GitLab