Scala 中的元组和布尔谓词元组

Koo*_*sha 2 scala tuples scala-3

关于如何在 Scala 3 中实现以下功能有什么想法吗?

我同意inline与否,一般来说,轻微的语法改变是可以的(即使是宏也可以)。但我不知道如果没有asInstanceOf.

type Pred[A] = A => Boolean

/** Computes values of predicates and combines them with `&&`.
  * 
  * The implementation does not use `asInstanceOf` or `isInstanceOf` */
inline def tupled[Args <: Tuple](inline preds: Tuple.Map[Args,Pred], inline args: Args): Boolean
Run Code Online (Sandbox Code Playgroud)

例子:

val pred: (Int => Boolean, Int => Boolean) = (_ < 0, _ > 0)

println(tupled[(Int, Int)](pred)( 1, 2)) // should print false
println(tupled[(Int, Int)](pred)(-1, 2)) // should print true
Run Code Online (Sandbox Code Playgroud)

Eas*_*sun 6

这个怎么样:

trait Reducer[Args <: Tuple, Preds <: Tuple]:
    def reduce(args: Args, preds: Preds): Boolean

object Reducer:
    given Reducer[EmptyTuple, EmptyTuple] = (args, preds) => true

    given [H, Args <: Tuple, Preds <: Tuple](using r: Reducer[Args, Preds]): Reducer[H *: Args, (H => Boolean) *: Preds] with
        def reduce(args: H *: Args, preds: (H => Boolean) *: Preds): Boolean = (args, preds) match
            case (ha *: ta, hp *: tp) => hp(ha) && r.reduce(ta, tp)

type Pred[A] = A => Boolean

/** Computes values of predicates and combines them with `&&`.
 *
 * The implementation does not use `asInstanceOf` or `isInstanceOf` */
def tupled[Args <: Tuple](preds: Tuple.Map[Args, Pred], args: Args)
                         (using r: Reducer[Args, Tuple.Map[Args, Pred]]): Boolean =
    r.reduce(args, preds)


scala> val pred: (Int => Boolean, Int => Boolean) = (_ < 0, _ > 0)
     |
     | println(tupled[(Int, Int)](pred, ( 1, 2))) // should print false
     | println(tupled[(Int, Int)](pred, (-1, 2)))
false
true
Run Code Online (Sandbox Code Playgroud)

如果交换参数,我们可以忽略类型参数:

scala> def tupled2[Args <: Tuple](args: Args, preds: Tuple.Map[Args, Pred])
     |                          (using r: Reducer[Args, Tuple.Map[Args, Pred]]): Boolean =
     |     r.reduce(args, preds)
     |
def tupled2[Args <: Tuple](args: Args, preds: Tuple.Map[Args, Pred])(using r: Reducer[Args, Tuple.Map[Args, Pred]]): Boolean

scala> val pred: (Int => Boolean, Int => Boolean) = (_ < 0, _ > 0)
     |
     | println(tupled2(( 1, 2), pred)) // should print false
     | println(tupled2((-1, 2), pred))
Run Code Online (Sandbox Code Playgroud)