J'ai commencé ma solution Shapeless à Project Euler Problem #2.Code Scala Shapeless pour Project Euler # 2
Je peux résumer ensemble tous les même bobards jusqu'à la Nth
même un avec ce code:
import shapeless._, nat._, ops.nat.Sum
trait Fibonacci[N <: Nat] { type Out <: Nat }
object Fibonacci {
type Aux[N <: Nat, Out0 <: Nat] = Fibonacci[N] { type Out = Out0 }
def apply[N <: Nat](i: Nat)(implicit fib: Aux[i.N, N], n: Witness.Aux[N]):N = n.value
implicit val fib0 = new Fibonacci[_0] { type Out = _2 }
implicit val fib1 = new Fibonacci[_1] { type Out = _3 }
implicit def fibN[I <: Nat, L <: Nat, M <: Nat](implicit l: Aux[I, L],
m: Aux[Succ[I], M],
sum: Sum[L, M]) =
new Fibonacci[Succ[Succ[I]]] { type Out = sum.Out }
}
trait Fibs[N <: Nat] { type Out <: Nat }
object Fibs {
type Aux[N <: Nat, Out0 <: Nat] = Fibs[N] { type Out = Out0 }
def apply[N <: Nat](i: Nat)(implicit fibs: Aux[i.N, N], n: Witness.Aux[N]):N = n.value
implicit def fibs0(implicit f: Fibonacci[_0]) = new Fibs[_0] { type Out = f.Out }
implicit def fibsN[N <: Nat, R <: Nat, Z <: Nat](implicit fib: Fibonacci.Aux[Succ[Succ[Succ[N]]], R],
fibs: Aux[N, Z],
sum: Sum[R, Z]) =
new Fibs[Succ[N]] {
type Out = sum.Out
}
}
Maintenant, je peux faire:
val (evenFibs0, evenFibs1) = (Fibs(0), Fibs(1))
typed[_2](evenFibs0)
typed[_10](evenFibs1)
Voilà comment je reçois tous les même bobards: Je commence par la séquence 2, 3, ..., et je résume tous les trois nombres de Fibonacci.
Maintenant, je suis coincé. Je voudrais avoir des fonctionnalités similaires à takeWhile
, donc je peux écrire une fonction qui accepte un limit
et retourne la somme de mes fibs pairs dont les termes ne dépassent pas cette limite. Des idées?
Voici mon effort pour ce que j'ai essayé jusqu'à présent:
trait EvenFibsWithLimit[N <: Nat, M <: Nat] { type Out <: Nat }
trait LowPriorityFibs3 {
type Aux[N <: Nat, M <: Nat, Out0 <: Nat] = EvenFibsWithLimit[N, M] { type Out = Out0 }
implicit def fibs0[M <: Nat] = new EvenFibsWithLimit[_0, M] { type Out = _0 }
implicit def fibsGT[N <: Nat, M <: Nat, O <: Nat](implicit f: EvenFibsWithLimit[N, M],
fib: Fibs.Aux[N, O],
l: ops.nat.LT[M, O]) = f
}
object EvenFibsWithLimit extends LowPriorityFibs3 {
def apply[N <: Nat, O <: Nat](limit: Nat)(implicit fibs: Aux[N, limit.N, O],
o: Witness.Aux[O]): O = o.value
implicit def fibsN[N <: Nat, M <: Nat, O <: Nat](implicit f: EvenFibsWithLimit[N, M],
f2: Fibs.Aux[Succ[N], O],
d: ops.nat.Diff[M, O]) =
new EvenFibsWithLimit[Succ[N], d.Out] {
type Out = O
}
}
L'idée était de soustraire récursive la limite de la sortie jusqu'à ce que la sortie est inférieure à la limite. Je peux définitivement sentir que quelque chose est éteint. Je ne pense pas avoir besoin de Diff
du tout .. J'ai aussi essayé d'autres variations, mais je reste coincé. Quand je compile, je reçois l'erreur diverging implicit expansion for fibsN.
EDIT:
Je pensais peut-être que je peux construire une HList
de mon Fibs
, et utiliser Selector
avec une classe de types de prédicats pour simuler un takeWhile
. Pensées?
Belle technique. Je commence à comprendre maintenant, merci. – beefyhalo