package rocks.matchmaker;

import java.util.function.Function;

public class PropertyMatcher<T, S> {

    private final Function<T, Option<?>> property;
    private final Matcher<S> matcher;

    private PropertyMatcher(Function<T, Option<?>> property, Matcher<S> matcher) {
        this.property = property;
        this.matcher = matcher;
    }

    //this reflects the fact that PropertyMatcher<F, T> is contravariant on F and covaraint on T
    @SuppressWarnings("unchecked cast")
    public static <T, R> PropertyMatcher<T, R> upcast(PropertyMatcher<? super T, ? extends R> matcher) {
        return (PropertyMatcher<T, R>) matcher;
    }

    public Function<T, Option<?>> getProperty() {
        return property;
    }

    public Matcher<S> getMatcher() {
        return matcher;
    }

    public static <F, T, R> PropertyMatcher<F, R> of(Function<F, Option<T>> property, Matcher<R> matcher) {
        //without the ::apply below, the type system is unable to drop the T type from Option
        return new PropertyMatcher<>(property::apply, matcher);
    }
}

@@ -90,12 +90,12 @@
 her%3C
-T, S
+F, R
 %3E %7B%0A
@@ -114,33 +114,33 @@
  final Function%3C
-T
+F
 , Option%3C?%3E%3E pro
@@ -164,33 +164,33 @@
 e final Matcher%3C
-S
+R
 %3E matcher;%0A%0A    
@@ -214,33 +214,33 @@
 atcher(Function%3C
-T
+F
 , Option%3C?%3E%3E pro
@@ -254,17 +254,17 @@
 Matcher%3C
-S
+R
 %3E matche
@@ -394,17 +394,17 @@
 cher%3CF, 
-T
+R
 %3E is con
@@ -436,17 +436,17 @@
 aint on 
-T
+R
 %0A    @Su
@@ -497,17 +497,17 @@
 static %3C
-T
+F
 , R%3E Pro
@@ -515,25 +515,25 @@
 ertyMatcher%3C
-T
+F
 , R%3E upcast(
@@ -556,17 +556,17 @@
 ? super 
-T
+F
 , ? exte
@@ -615,17 +615,17 @@
 Matcher%3C
-T
+F
 , R%3E) ma
@@ -658,17 +658,17 @@
 unction%3C
-T
+F
 , Option
@@ -739,17 +739,17 @@
 Matcher%3C
-S
+R
 %3E getMat
@@ -971,17 +971,17 @@
 rop the 
-T
+R
  type fr

Rename type variables in `PropertyMatcher`