Ответ 1
Обновление: я только что видел ваше редактирование, что означает, что вы уже рассмотрели проблему, отмеченную в первых параграфах здесь, но я надеюсь, что остальное полезно.
Проблема заключается в том, что ваш экземпляр SizedHListAux
не выводится:
scala> implicitly[SizedHListAux[String, _1, String :: HNil]]
<console>:25: error: could not find implicit value for parameter e...
К счастью, это легкое исправление:
object SizedHListAux {
implicit def base[A] = new SizedHListAux[A, _0, HNil] {}
implicit def induct[A, H <: HList, N <: Nat, P <: Nat](implicit
r: PredAux[N, P],
k: SizedHListAux[A, P, H]
) = new SizedHListAux[A, N, A :: H] {}
}
Я только что удалил параметр типа R <: PredAux[N, P]
и набрал r
соответствующим образом. Я также удалил параметр неиспользуемого типа H
на base
, хотя он не вызывал проблем - он просто ничего не делал.
Это почти все - теперь все экземпляры для fromF1
выводятся:
scala> SomeFun.fromF1((tfn, thedata))
res0: SomeFun{type Result = (Unit, List[String])} = [email protected]
Вы все равно не получите представление от типа (tfn, thedata)
до SomeFun
. Рассмотрим следующий упрощенный пример:
scala> trait Foo
defined trait Foo
scala> trait Bar[A, B]
defined trait Bar
scala> implicit def toInt[F <: Foo, X](f: F)(implicit ev: Bar[F, X]) = 42
toInt: [F <: Foo, X](f: F)(implicit ev: Bar[F,X])Int
scala> implicit object fooBar extends Bar[Foo, String]
defined module fooBar
scala> toInt(new Foo {})
res0: Int = 42
scala> implicitly[Foo => Int]
<console>:12: error: No implicit view available from Foo => Int.
implicitly[Foo => Int]
Итак, хотя у нас есть неявный метод в области видимости, который преобразует Foo
в Int
, что X
вызывает проблемы для компилятора, когда он пытается найти представление из Foo
в Int
.
В вашем случае я бы избегал этого ограничения, пропустив бизнес SomeFun
и имея метод, который принимает (P => T, List[A])
и возвращает (T, List[A])
.
Я также заметил, что как ToArity
, так и SizedHListAux
кажутся ненужными, так как вы можете собрать те же доказательства с TuplerAux
, LengthAux
и LUBConstraint
. Например:
import shapeless._
trait SomeFun {
type Result
def apply(): Result
}
implicit def fromF1[T, A, P <: Product, N <: Nat, H <: HList](
f1: (P => T, List[A])
)(implicit
tp: TuplerAux[H, P],
hl: LengthAux[H, N],
toHL: FromTraversable[H],
allA: LUBConstraint[H, A],
toI: ToInt[N]
) = new SomeFun {
type Result = (T, List[A])
def apply(): Result = {
val (f, as) = f1
val (ts, rest) = (as.take(toI()), as.drop(toI()))
f((toHL(ts).get).tupled) -> rest
}
}
И затем:
val tfn = (x: (String, String)) => println("%s and %s".format(x._1, x._2))
val thedata = List("foo", "bar", "baz", "bob")
val sf = fromF1((tfn, thedata))
И наконец:
scala> sf()
foo and bar
res2: (Unit, List[String]) = ((),List(baz, bob))
Не нужно раздражать prodN
шаблона.