Играя с бесформенными натуральными числами в волнении, мне интересно, что может быть лучшим подходом для получения целочисленного значения, например продукт нац.
Выдержка из бесформенного nat.scala
:
trait Prod[A <: Nat, B <: Nat] {
type Out <: Nat
}
trait ProdAux[A <: Nat, B <: Nat, C <: Nat]
object Prod {
implicit def prod[A <: Nat, B <: Nat, C <: Nat](implicit diff : ProdAux[A, B, C]) = new Prod[A, B] {
type Out = C
}
}
object ProdAux {
import Nat._0
implicit def prod1[B <: Nat] = new ProdAux[_0, B, _0] {}
implicit def prod2[A <: Nat, B <: Nat, C <: Nat, D <: Nat]
(implicit ev1 : ProdAux[A, B, C], ev2 : SumAux[B, C, D]) = new ProdAux[Succ[A], B, D] {}
}
До сих пор я придумал простое определение
def toInt[A <: Nat, B <: Nat, C <: Nat](p: Prod[A, B])
(implicit paux: ProdAux[A, B, C], iv: ToInt[C]): Int = iv()
На самом деле этот подход потребует несколько избыточных реализаций эквивалентного кода, например суммы, разности, факториалы и т. д. Поэтому я бы предпочел использовать метод «по умолчанию» toInt[A <: Nat]
.
Как бы вы это сделали? И можно ли использовать внутренние типы (Prod#Out
, Sum#Out
, ...)?