Учитывая следующую попытку извлечения рекурсивной суммы двух HList
, как показано ниже:Сумма двух идентичных HList во время компиляции?
(. Помилования Product
в его имени сейчас, пожалуйста)
package net
import shapeless._
import shapeless.nat._
import shapeless.ops.nat.{Sum, Prod, Mod}
trait SumZippedProduct[L, M] {
type S
}
object SumZippedProduct {
type Aux[L, M, O] = SumZippedProduct[L, M] {
type S = O
}
def apply[L <: HList, M <: HList](implicit ev: SumZippedProduct[L, M]) = ev
// LH - L's head
// L - HList
// MH - M's head
// M - HList
// RS - Recursive Sum (L + H)
// CS - Current Sum (LH + RH)
// E - RS + CS
implicit def sumZippedInductiveEq5[LH <: Nat, L <: HList, MH <: Nat, M <: HList, RS <: Nat, CS <: Nat, E <: Nat](
implicit ev: SumZippedProduct.Aux[L, M, RS],
curr: Sum.Aux[LH, MH, CS],
total: Sum.Aux[CS, RS, E]
): SumZippedProduct[LH :: L, MH :: M] = new SumZippedProduct[LH :: L, MH :: M] {
type S = E
}
implicit val hnils: SumZippedProduct[HNil, HNil] = new SumZippedProduct[HNil, HNil] {
type S = _0
}
}
При попытке его, он работает, Я думаю, для HNil
случая, но не для 1-го элемента HList
:
scala> import net.SumZippedProduct
import net.SumZippedProduct
scala> import shapeless._, nat._
import shapeless._
import nat._
// expecting 0 (0 + 0)
scala> SumZippedProduct[HNil, HNil]
res0: net.SumZippedProduct[shapeless.HNil,shapeless.HNil] = [email protected]
// expecting _4 (1 + 3)
scala> SumZippedProduct[_1 :: HNil, _3 :: HNil]
<console>:19: error: could not find implicit value for parameter ev: net.SumZippedProduct[shapeless.::[shapeless.nat._1,shapeless.HNil],shapeless.::[shapeless.nat._3,shapeless.HNil]]
SumZippedProduct[_1 :: HNil, _3 :: HNil]
^
Почему не компилировать при прохождении _1 :: HNil
и _3 :: HNil
?
Также, как я могу получить _0
в res0
?
scala> res0.S
<console>:20: error: value S is not a member of net.SumZippedProduct[shapeless.HNil,shapeless.HNil]
res0.S
^
Примечание. Я ценю, если такая реализация уже существует в бесформенной, но я задаю этот вопрос, чтобы узнать.
Для моего собственного понимания, каково различие между 'ev.type' и' ev', за тип возврата «SumZippedProduct # apply»? –
Это одноэлементный тип 'ev', но он не выводится автоматически. Поэтому, если вы явно не заявляете, что хотите использовать тип singleton как возвращаемый тип 'SumZippedProduct [L, M]', вы будете выведены, и вы потеряете информацию о типе. –
Вы также можете написать как 'def apply [L <: HList, M <: HList] (неявный ev: SumZippedProduct [L, M]): SumZippedProduct.Aux [L, M, ev.S] = ev'. –