Scala中任意输入参数的部分函数应用

aiazj4mn  于 2023-01-26  发布在  Scala
关注(0)|答案(1)|浏览(131)

我想知道以下内容在Scala中是否可行:
给定R^n中的某个向量x = (x_1, x_2, ..., x_n)和将R^nMap到R的函数f,我想在Scala中复制这个概念。(即,当应用单个值x_i时,返回仅针对其输入域的子集定义的函数)。例如,当n = 2时,定义f(x, y) = sin(x + y),然后平凡地定义f(2, y) = sin(2 + y)
然而,维度(n〉0)可以随情况而变化,并且甚至可以在输入中提供。
n = 2的部分应用为:

def leftPartialFunction(f: (Double, Double) => Double)(x: Double): Double => Double = f(x, _)

但是如何将其推广到任意的n,例如,如何在位置i上应用函数,我假设类似这样的情况不会起作用:

def partialFunction(f: IndexedSeq[Double] => Double)(xi: Double): IndexedSeq[Double] => Double =  .... // cannot work well with indexed seq as they are not "disjoint"
bgtovc5b

bgtovc5b1#

尝试以下partialFunction实现:

import shapeless.{::, HList, HNil, Nat, Succ}
import shapeless.ops.function.{FnFromProduct, FnToProduct}
import shapeless.ops.hlist.{At, Drop, Prepend, Take}

def partialFunction[N <: Nat, F, X,
                    L <: HList, Y, L1 <: HList, L2 <: HList, L3 <: HList
                   ](i: N)(f: F)(xi: X)(implicit
  fnToProduct: FnToProduct.Aux[F, L => Y],
  at: At.Aux[L, N, X],
  take: Take.Aux[L, N, L1],
  drop: Drop.Aux[L, Succ[N], L2],
  prepend: Prepend.Aux[L1, L2, L3],
  fnFromProduct: FnFromProduct[L3 => Y],
  take1: Take.Aux[L3, N, L1],
  drop1: Drop.Aux[L3, N, L2],
  prepend1: Prepend.Aux[L1, X :: L2, L],
): fnFromProduct.Out =
  fnFromProduct(l3 => fnToProduct(f)(prepend1(take1(l3), xi :: drop1(l3))))

测试:

import shapeless.Nat._1

val f: (Int, Boolean, Double) => String = (i, b, d) => s"i=$i, b=$b, d=$d"

f(1, true, 2.0) // i=1, b=true, d=2.0

val f1 = partialFunction(_1)(f)(true)

f1: ((Int, Double) => String)

f1(1, 2.0) // i=1, b=true, d=2.0

您也可以写入partialFunction(Nat(1))(f)(true)而不是partialFunction(_1)(f)(true)

相关问题