Skip to content

Instantly share code, notes, and snippets.

@non
Last active February 13, 2018 20:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save non/4d83d53601a990560c36b4cd0865c4e5 to your computer and use it in GitHub Desktop.
Save non/4d83d53601a990560c36b4cd0865c4e5 to your computer and use it in GitHub Desktop.
nested opaque types demo
package object demo {
opaque type Collection[A] = Array[A]
object Collection {
opaque type Pointer[A] = Int
object Pointer {
def first(c: Collection[A]): Option[Pointer[A]] =
if (c.length > 0) Some(0) else None
def next(c: Collection[A], p: Pointer[A]): (A, Option[Pointer[A]]) =
(c(p), if (c.length - 1 <= p) None else Some(p + 1))
}
}
}
trait Module[C[_]] {
type Pointer[I <: Singleton]
def isEmpty[A](c: C[A]): Boolean
def first[A](c: C[A]): Option[Pointer[c.type]]
def next[A](c: C[A])(p: Pointer[c.type]): Option[Pointer[c.type]]
def get[A](c: C[A])(p: Pointer[c.type]): A
}
object ArrayModule[Array[_]] {
opaque type Pointer[I <: Singleton] = Int
object Pointer {
// code that treats Pointer as an Int must go in here.
def first[A](c: Array[A]): Option[Pointer[c.type]] =
if (c.length == 0) None else Some(0)
def next[A](c: Array[A])(p: Pointer[c.type]): Option[Pointer[c.type]] =
if (c.length > p + 1) Some(p + 1) else None
def get[A](c: C[A])(p: Pointer[c.type]): A =
c(p)
}
def isEmpty[A](c: Array[A]): Boolean =
c.isEmpty
def first[A](c: Array[A]): Option[Pointer[c.type]] =
Pointer.first(c)
def next[A](c: Array[A])(p: Pointer[c.type]): Option[Pointer[c.type]] =
Pointer.next(c)(p)
def get[A](c: Array[A])(p: Pointer[c.type]): A =
Pointer.get(c)(p)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment