I have a set of classes that describe rules that can be combined to test some data. I have the following (simplified) definition:
sealed trait Rule[I]
case class Input[I](i:I, r:Rule[I]) extends Rule[I]
case class Proposition[I,R](check: I => Boolean) extends Rule[I]
case class And[I](r1: Rule[I], r2: Rule[I]) extends Rule[I]
case class Or[I](r1: Rule[I], r2: Rule[I]) extends Rule[I]
I have a function that matches the above cases takes an input and generates a true/false result. Something like:
def fold[In,Out](r: Rule[In], data: In, acc: Report, add: (Report, QAResult[_]) => Report): Report =
def fold[I,O](r: Rule[I], data: I, acc: Report): Report =
r match
case Input(d, r) =>
fold(r, d, acc)
case Proposition(c) =>
add(acc, c(data))
case And(c1, c2) =>
val r1 = fold(c1, data, acc)
if r1._2 then fold(c2, data, r1) else r1
case Or(c1, c2) =>
val r1 = fold(c1, data, acc)
if !r1._2 then fold(c2, data, r1) else r1
case Pair(r1:Rule[_], r2:Rule[_]) =>
val v1 = data._1
???
fold(r, data, acc)
Now I would like to be able to do something like:
val p = Pair(Proposition(f1), Proposition(f2))
where :

p
is aRule[(T1,T2)]

f1
is aT1=>Boolean

f2
isT2=>Boolean
So I defined:
case class Pair[I1,I2](r1: Rule[I1], r2: Rule[I2]) extends Rule[(I1,I2)]
The problem is that I do not know how to “cast” the I
in the function above to a tuple. I get the error:
[error] 405  val v1 = data._1
[error]  ^^^^^^^
[error] value _1 is not a member of I
[error] 
[error] where: I is a type in method fold with bounds >: (I1$1, I2$1) and <: (I1$1, I2$1)
Is this possible?
TIA