```package scalaz

trait Length[-L[_]] {
def len[A](a: L[A]): Int
}

object Length {
import Scalaz._

implicit def IdentityLength: Length[Identity] = new Length[Identity] {
def len[A](a: Identity[A]) = 1
}

implicit def NonEmptyListLength[A]: Length[NonEmptyList] = new Length[NonEmptyList] {
def len[A](a: NonEmptyList[A]) = a.list.length
}

implicit def ZipStreamLength: Length[ZipStream] = new Length[ZipStream] {
def len[A](a: ZipStream[A]) = a.value.length
}

implicit def Tuple1Length: Length[Tuple1] = new Length[Tuple1] {
def len[A](a: Tuple1[A]) = 1
}

implicit def Function0Length: Length[Function0] = new Length[Function0] {
def len[A](a: () => A) = 1
}

implicit def OptionLength: Length[Option] = new Length[Option] {
def len[A](a: Option[A]) = a map (_ => 1) getOrElse 0
}

implicit def EitherLeftLength[X]: Length[({type λ[α]=Either.LeftProjection[α, X]})#λ] = new Length[({type λ[α]=Either.LeftProjection[α, X]})#λ] {
def len[A](a: Either.LeftProjection[A, X]) = a.e match {
case Right(_) => 0
case Left(_) => 1
}
}

implicit def EitherRightLength[X]: Length[({type λ[α]=Either.RightProjection[X, α]})#λ] = new Length[({type λ[α]=Either.RightProjection[X, α]})#λ] {
def len[A](a: Either.RightProjection[X, A]) = a.e match {
case Right(_) => 1
case Left(_) => 0
}
}

implicit def ValidationLength[X]: Length[({type λ[α]=Validation[X, α]})#λ] = new Length[({type λ[α]=Validation[X, α]})#λ] {
def len[A](a: Validation[X, A]) = a match {
case Success(_) => 1
case Failure(_) => 0
}
}

implicit def ValidationFailureLength[X]: Length[({type λ[α]=FailProjection[α, X]})#λ] = new Length[({type λ[α]=FailProjection[α, X]})#λ] {
def len[A](a: FailProjection[A, X]) = a.validation match {
case Success(_) => 0
case Failure(_) => 1
}
}

implicit def ArraySeqLength: Length[ArraySeq] = new Length[ArraySeq] {
def len[A](a: ArraySeq[A]) = a.length
}

implicit def ArrayLength: Length[Array] = new Length[Array] {
def len[A](a: Array[A]) = a.length
}

implicit def ImmutableArrayLength: Length[ImmutableArray] = new Length[ImmutableArray] {
def len[A](a: ImmutableArray[A]) = a.length
}

import FingerTree.ftip2ft
implicit def RopeLength: Length[Rope] = new Length[Rope] {
def len[A](a: Rope[A]) = a.value.measure
}

implicit def IterableLength: Length[Iterable] = new Length[Iterable] {
def len[A](a: Iterable[A]) = {
var n = 0
val i = a.iterator
while(i.hasNext) {
n = n + 1
i.next
}

n
}
}

implicit def JavaIterableLength: Length[java.lang.Iterable] = new Length[java.lang.Iterable] {
def len[A](a: java.lang.Iterable[A]) = {
var n = 0
val i = a.iterator
while(i.hasNext) {
n = n + 1
i.next
}

n
}
}

import java.util.concurrent.Callable

implicit def CallableLength: Length[Callable] = new Length[Callable] {
def len[A](a: Callable[A]) = 1
}
}

```