在 GitHub 上編輯此頁面

元組函數

元組函式

對於限定為 22 以下元的函式,可以使用超載對所有函式類型進行一些運算。現在我們有了函式和元組,已廣義化為22 以上的元,因此超載不再是選項。類型類別 TupleFunction 提供一種方式,可直接抽象出任何元的函式,並將其轉換為等效函式,在單一元組中接收所有引數。

/** Type class relating a `FunctionN[..., R]` with an equivalent tupled function `Function1[TupleN[...], R]`
 *
 *  @tparam F a function type
 *  @tparam G a tupled function type (function of arity 1 receiving a tuple as argument)
 */
@implicitNotFound("${F} cannot be tupled as ${G}")
sealed trait TupledFunction[F, G] {
  def tupled(f: F): G
  def untupled(g: G): F
}

如果

  • F 是元為 N 的函式類型
  • G 是具有大小為 N 的單一元組引數的函式,其類型等於 F 的引數
  • F 的回傳類型等於 G 的回傳類型
  • FG 是相同類型的函式(兩者都是 (...) => R 或兩者都是 (...) ?=> R
  • 如果僅實例化 FG 之一,則會推論出第二個。

範例

TupledFunction 可用於將 Function1.tupled、... Function22.tupled 方法推廣至任何 arities 的函數。下列定義 tupled擴充方法完整範例)。

/** Creates a tupled version of this function: instead of N arguments,
 *  it accepts a single [[scala.Tuple]] with N elements as argument.
 *
 *  @tparam F the function type
 *  @tparam Args the tuple type with the same types as the function arguments of F
 *  @tparam R the return type of F
 */
extension [F, Args <: Tuple, R](f: F)
  def tupled(using tf: TupledFunction[F, Args => R]): Args => R = tf.tupled(f)

TupledFunction 可用於將 Function.untupled 推廣至任何 arities 的函數(完整範例)。

/** Creates an untupled version of this function: instead of a single argument of type [[scala.Tuple]] with N elements,
 *  it accepts N arguments.
 *
 *  This is a generalization of [[scala.Function.untupled]] that work on functions of any arity
 *
 *  @tparam F the function type
 *  @tparam Args the tuple type with the same types as the function arguments of F
 *  @tparam R the return type of F
 */
extension [F, Args <: Tuple, R](f: Args => R)
  def untupled(using tf: TupledFunction[F, Args => R]): F = tf.untupled(f)

TupledFunction 也可用於將 Tuple1.composeTuple1.andThen 方法推廣至組合更大 arities 的函數,以及傳回 tuple 的函數。

/** Composes two instances of TupledFunction into a new TupledFunction, with this function applied last.
 *
 *  @tparam F a function type
 *  @tparam G a function type
 *  @tparam FArgs the tuple type with the same types as the function arguments of F and return type of G
 *  @tparam GArgs the tuple type with the same types as the function arguments of G
 *  @tparam R the return type of F
 */
extension [F, G, FArgs <: Tuple, GArgs <: Tuple, R](f: F)
  def compose(g: G)(using tg: TupledFunction[G, GArgs => FArgs], tf: TupledFunction[F, FArgs => R]): GArgs => R = {
  (x: GArgs) => tf.tupled(f)(tg.tupled(g)(x))
}
在本文中