higher-kinded heterogeneous lists: MList[M[_]]

natural transformations: ~>[A[_], B[_]]
Scala 2.8
This commit is contained in:
Mark Harrah 2010-05-30 18:42:58 -04:00
parent 83fa048026
commit 7927d8bdad
7 changed files with 90 additions and 60 deletions

View File

@ -0,0 +1,22 @@
package sbt
import Types._
sealed trait HList
{
type Up <: MList[Id]
def up: Up
}
sealed trait HNil extends HList
{
type Up = MNil[Id]
def up = MNil
def :+: [G](g: G): G :+: HNil = HCons(g, this)
}
object HNil extends HNil
final case class HCons[H, T <: HList](head : H, tail : T) extends HList
{
type Up = MCons[H, T#Up, Id]
def up = MCons[H,T#Up, Id](head, tail.up)
def :+: [G](g: G): G :+: H :+: T = HCons(g, this)
}

View File

@ -1,29 +0,0 @@
// stripped down version of http://trac.assembla.com/metascala/browser/src/metascala/HLists.scala
// Copyright (c) 2009, Jesper Nordenberg
// new BSD license, see licenses/LICENSE_MetaScala
package xsbt
object HLists extends HLists
trait HLists
{
object :: { def unapply[H,T<:HList](list: HCons[H,T]) = Some((list.head,list.tail)) }
type ::[H, T <: HList] = HCons[H, T]
}
object HNil extends HNil
sealed trait HList {
type Head
type Tail <: HList
}
sealed class HNil extends HList {
type Head = Nothing
type Tail = HNil
def ::[T](v : T) = HCons(v, this)
}
final case class HCons[H, T <: HList](head : H, tail : T) extends HList {
type Head = H
type Tail = T
def ::[T](v : T) = HCons(v, this)
}

View File

@ -0,0 +1,42 @@
package sbt
import Types._
sealed trait MList[M[_]]
{
type Map[N[_]] <: MList[N]
def map[N[_]](f: M ~> N): Map[N]
type Down <: HList
def down: Down
def toList: List[M[_]]
}
final case class MCons[H, T <: MList[M], M[_]](head: M[H], tail: T) extends MList[M]
{
type Down = M[H] :+: T#Down
def down = HCons(head, tail.down)
type Map[N[_]] = MCons[H, T#Map[N], N]
def map[N[_]](f: M ~> N) = MCons( f(head), tail.map(f) )
def :^: [G](g: M[G]): MCons[G, MCons[H, T, M], M] = MCons(g, this)
def toList = head :: tail.toList
}
sealed class MNil[M[_]] extends MList[M]
{
type Down = HNil
def down = HNil
type Map[N[_]] = MNil[N]
def map[N[_]](f: M ~> N): MNil[N] = new MNil[N]
def :^: [H](h: M[H]): MCons[H, MNil[M], M] = MCons(h, this)
def toList = Nil
}
object MNil extends MNil[Id]
{
implicit def apply[N[_]]: MNil[N] = new MNil[N]
}

View File

@ -1,7 +1,3 @@
Simple Build Tool: Collection Component
Copyright 2009 Mark Harrah
Licensed under BSD-style license (see LICENSE)
Portions based on MetaScala
Copyright (c) 2009, Jesper Nordenberg
Licensed under BSD-style license (see licenses/LICENSE_MetaScala)
Copyright 2010 Mark Harrah
Licensed under BSD-style license (see LICENSE)

View File

@ -1,25 +0,0 @@
/* sbt -- Simple Build Tool
* Copyright 2009 Mark Harrah
*/
package xsbt
import scala.collection.{mutable,immutable}
// immutable.HashSet is not suitable for multi-threaded access, so this
// implementation uses an underlying immutable.TreeHashMap, which is suitable
object TreeHashSet
{
def apply[T](contents: T*) = new TreeHashSet(immutable.TreeHashMap( andUnit(contents) : _*))
def andUnit[T](contents: Iterable[T]) = contents.map(c => (c,()) ).toSeq
}
final class TreeHashSet[T](backing: immutable.TreeHashMap[T,Unit]) extends immutable.Set[T]
{
import TreeHashSet.andUnit
override def contains(t: T) = backing.contains(t)
override def ++(s: Iterable[T]) = new TreeHashSet(backing ++ andUnit(s))
override def +(s: T) = ++( Seq(s) )
override def -(s: T) = new TreeHashSet(backing - s)
override def elements = backing.keys
override def empty[A] = TreeHashSet[A]()
override def size = backing.size
}

View File

@ -0,0 +1,16 @@
package sbt
trait TypeFunctions
{
type Id[X] = X
trait Const[A] { type Apply[B] = A }
trait Down[M[_]] { type Apply[B] = Id[M[B]] }
trait ~>[A[_], B[_]]
{
def apply[T](a: A[T]): B[T]
}
def Id: Id ~> Id =
new ~>[Id, Id] { def apply[T](a: T): T = a }
}
object TypeFunctions extends TypeFunctions

View File

@ -0,0 +1,8 @@
package sbt
object Types extends TypeFunctions
{
val :^: = MCons
val :+: = HCons
type :+:[H, T <: HList] = HCons[H,T]
}