如何通过组合输入元组来组成一元一元的函数

时间:2015-09-13 10:55:29

标签: scala shapeless

我现在一直在玩无形状。 但是,昨天我在尝试编写元组函数时遇到了困难。

我特别关注的是将两个一元函数f1: T => Rf2: 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 _

我一直在努力为元组操作lastinit提供隐式证明,因此上述代码无法编译!

从逻辑的角度来看,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)

0 个答案:

没有答案