我现在一直在玩无形状。 但是,昨天我在尝试编写元组函数时遇到了困难。
我特别关注的是将两个一元函数f1: T => R
和f2: R => U => S
组合成f: TU => S
,其中T是一个元组N和TU := (t1, ... , tn, u)
import shapeless.ops.tuple._
implicit class Composable[T <: Product, R](val f1: T => R) extends AnyVal{
def compose2[U, S](f2: R => U => S)(implicit p: Prepend[T, Tuple1[U]]): (p.Out => S) = {
// how to provide the two required implicits for Last[p.Out] and Init[p.Out]?
tu => f1.andThen(f2)(tu.init)(tu.last)
}
}
val f1: ((Int, Int)) => Int = x => x._1 * x._2
val f2: ((Int, Int, Int)) => Int = f1.compose2((y: Int) => (x3: Int) => x3 + y).apply _
我一直在努力为元组操作last
和init
提供隐式证明,因此上述代码无法编译!
从逻辑的角度来看,Prepend
的结果感觉微不足道,但我无法找到方法。所以欢迎任何想法:)
使用无形的设施抽象过度我更加接近:
import shapeless.ops.function.{FnFromProduct, FnToProduct}
import shapeless.{::, HList}
implicit class Composable[F](val f: F) extends AnyVal{
// the new param U is appended upfront
def compose2[I <: HList, R, U, S](f2: R => U => S)
(implicit ftp: FnToProduct.Aux[F, I => R], ffp: FnFromProduct[U :: I => S]): ffp.Out = {
ffp(list => f2.compose(ftp(f))(list.tail)(list.head))
}
}
val f1: (Int, Int) => Int = (x1,x2) => x1 * x2
val f2: (Int, Int, Int) => Int = f1.compose2((y: Int) => (x3: Int) => x3 + y).apply _
这样可行,但我又一次真的在寻找compose2
来处理一元tupled Function1
。此外,这会导致f: (U, t1, ..., tn) => S
而不是f: TU => S
TU := (t1, ... , tn, u)
。