Jestem nowy, bezkształtny i próbowałem ćwiczyć niektóre poziomy programowania. Zrobiłem Problem #1 from Project Euler jako moje pierwsze wyzwanie.Scala bezkształtny kod dla projektu Euler # 1
zacząłem pisząc regularne kod scala:
object ProjectEuler1 {
def e1(limit: Int) = (1 until limit).foldLeft(0) {
case (acc, x) if x % 3 * x % 5 == 0 => acc + x
case (acc, _) => acc
}
val out = e1(10)
assert(out == 23)
}
Potem wymyślił ten pracuje realizacja bezkształtne użyciu poly
:
object ProjectEuler1Shapeless extends App {
import shapeless._
import nat._
import ops.nat._
import poly._
import test.typed
trait eLP extends Poly1 {
implicit def default[A <: Nat] = at[A] { _ => _0 }
}
object e extends eLP {
implicit def match3[A <: Nat](implicit ev: Mod.Aux[A, _3, _0]) = at[A](identity)
implicit def match5[A <: Nat](implicit ev: Mod.Aux[A, _5, _0]) = at[A](identity)
}
object sum extends Poly2 {
implicit def sum[A <: Nat, B <: Nat, Z <: Nat](implicit s: Sum.Aux[A, B, Z],
z: Witness.Aux[Z]) =
at[A, B] { (_, _) => z.value }
}
type _23 = Succ[_22]
val l = _1 :: _2 :: _3 :: _4 :: _5 :: _6 :: _7 :: _8 :: _9 :: HNil
val out = l.map(e).foldLeft(_0)(sum)
typed[_23](out)
}
Następnie chciałem zmienić funkcję tak, że nie trzeba ręcznie tworzyć listy. Zamiast tego akceptuje "limit" jako argument, jak zwykły kod scala. Wpadłem na to:
object ProjectEuler1Shapeless2 extends App {
import shapeless._
import nat._
import ops.nat._
import test.typed
class E1[I <: Nat, N <: Nat]
trait ELP0 {
implicit def default[I <: Nat, M <: Nat] = new E1[I, _0]
}
trait ELP1 extends E1LP0 {
implicit def match3[A <: Nat](implicit ev: Mod.Aux[A, _3, _0]) = new E1[A, A]
implicit def match5[A <: Nat](implicit ev: Mod.Aux[A, _5, _0]) = new E1[A, A]
}
object E1 extends E1LP1 {
implicit def combine[I <: Nat, L <: Nat, M <: Nat](implicit e1: E1[I, L],
m: E1[Succ[I], M],
sum: Sum[L, M]) =
new E1[Succ[Succ[I]], sum.Out]
}
def e1[N <: Nat](limit: Nat)(implicit e: E1[limit.N, N], w: Witness.Aux[N]): N = w.value
val f1 = e1(1)
typed[_0](f1)
val f2 = e1(2)
typed[_0](f2)
val f3 = e1(3)
typed[_3](f3) // Does not compile!
}
Utknąłem tutaj. Kompilator mówi mi, że znalazł _0
. Chyba odbiera instancję od def default
.
Wszelkie wskazówki, jak mogę to naprawić? Mam wrażenie, że moja strategia rozwiązania tego problemu może być trochę dziwna. Wszelkie wskazówki na temat tego, w jaki sposób mogę uczynić ten bezkształtny kod bardziej idiomatycznym, są bardzo doceniane.
Moja oryginalna strategia polegała na stworzeniu hylomorfizmu. Zauważyłem, że jest unfold example in the shapeless git, ale jego złożoność ucieka mi w tej chwili.
To jest piękne. Dokładnie tego chciałem i bardzo edukacyjnie. Wspaniała lekcja, w jaki sposób modelować swoje myślenie za pomocą aplikacji Shapeless. Zdecydowanie wykorzystam tę odpowiedź jako punkt odniesienia do rozwiązywania przyszłych problemów. – beefyhalo
Nie można 'sumN' używać' P' i 'Succ [P]' zamiast 'Succ [P]' i 'Succ [Succ [P]]' lub czy jest coś czego mi brakuje? – beefyhalo
@beefyhalo Ach, to możliwe - pisaliśmy o tym podczas dzisiejszej konferencji. –