实现具有One Inhabitant的类型的值

bee*_*alo 21 macros scala type-level-computation shapeless

感谢@ MilesSabin的回答,我可以编写一个类型级的Fibonacci序列:

sealed trait Digit
case object Zero extends Digit
case object One extends Digit

sealed trait Dense { type N <: Dense }
sealed trait DNil extends Dense { type N = DNil }
case object DNil extends DNil
final case class ::[+H <: Digit, +T <: Dense](digit: H, tail: T) extends Dense {
  type N = digit.type :: tail.N
}

/* The `A`th Fibonacci number is `B` */
trait Fib[A <: Dense, B <: Dense]

object Fib {
  implicit val f0 = new Fib[_0, _0] {}
  implicit val f1 = new Fib[_1, _1] {}

  implicit def f2[A <: Dense, P <: Dense, P2 <: Dense, F <: Dense, F2 <: Dense]
   (implicit p: Pred.Aux[A, P],
             p2: Pred.Aux[P, P2],
             f: Fib[P, F],
             f2: Fib[P2, F2],
             sum: Sum[F, F2]): Fib[A, sum.Out] = new Fib[A, sum.Out] {}
}

implicitly[Fib[_7, _13]]
Run Code Online (Sandbox Code Playgroud)

我真的希望能够做的就是一WitnessDense,并使用它,如:

def apply[Out <: Dense](n: Dense)(implicit f:Fib[n.N, Out], w:Witness.Aux[Out]): Out
  = w.value
Run Code Online (Sandbox Code Playgroud)

Scala告诉我它不能召唤一个Witness实例.我猜这是因为我对自然数的类型级编码是一个位的链表,而不是单例类型.我无法理解为什么Witness不起作用,因为像一个班级只有一个居民_7.

我要做的是为只有一个可能值的类型实现一个值.这样我就可以Out直接从中获得apply.

我认为可能的解决方案可能会利用隐式宏.

欢迎任何和所有的想法.如果问题不明确,我建议你留言.