2014-06-10 7 views
7

Ich versuche, formlos, und ich kam in dem zu verstehen:Warum ist das _0 Nat in Shapeless eine Klasse statt eines Objekts?

// Base trait for type level natural numbers. 
trait Nat { 
    type N <: Nat 
} 

// Encoding of successor. 
case class Succ[P <: Nat]() extends Nat { 
    type N = Succ[P] 
} 

// Encoding of zero. 
class _0 extends Nat { 
    type N = _0 
} 

_0 ist ein besonderer und einzigartiger Fall, wie Nil für ein List. _0 hat keinen Vorgänger. Warum ist es kein Objekt/Case-Objekt (was ein Singleton ist)? HList s scheint dies zu tun:

// `HList` ADT base trait. 
sealed trait HList 

// Non-empty `HList` element type. 
final case class ::[+H, +T <: HList](head : H, tail : T) extends HList { 
    override def toString = head+" :: "+tail.toString 
} 

// Empty `HList` element type. 
sealed trait HNil extends HList { 
    def ::[H](h : H) = shapeless.::(h, this) 
    override def toString = "HNil" 
} 

// Empty `HList` value. 
case object HNil extends HNil 

Antwort

0

(nur raten, ich weiß nicht, den ursprünglichen Grund.)

Vielleicht, so dass ein Typ_0 verfügbar ist (es wie ausdrücklich passiert in def fun[N <: Nat] = ???; fun[_0] , oder einfacher, Implikate über diesen Typ zu definieren).

Wenn _0 ein Singleton gewesen wäre, wäre nur der Typ _0.type verfügbar gewesen.

Und das gleiche für HNil?

+1

Es ist kein guter Grund, es nicht zu einem Singleton-Typ zu machen. Um Bequemlichkeit zu haben, von der Sie sprechen, können Sie einfach 'case object _0 Extends Nat' und' type _0 = _0.type' schreiben – laughedelic