/ / Scala przeciążone funkcje wyższego rzędu powodują błąd typu - scala, typy, przeciążenie, przeciążenie metody

Scala przeciążone funkcje wyższego rzędu powodują błąd typu - scala, typy, przeciążenie, przeciążanie metod

Mam przeciążoną metodę zdefiniowaną w następujący sposób:

def g(f: () ⇒ Double): Object = null
def g(f: Double ⇒ Double): Object = null
def g(f: (Double, Double) ⇒ Double): Object = null

def h(f: (Double, Double) ⇒ Double): Object = null

Podczas h(math.max _) działa zgodnie z oczekiwaniami, dzwoniąc g(math.max _) wyświetla błąd „Metoda przeciążona ... nie można zastosować do ((Int, Int) => Int)”. Wygląda na to, że kompilator wybrał wersję Int math.max zamiast wersji Double.

Jak mogę wywołać moją przeciążoną metodę g z math.max jako parametrem? Byłbym dodatkową korzyścią, gdybym mógł po prostu zadzwonić g(math.max) bez podkreślenia.

Odpowiedzi:

3 dla odpowiedzi № 1

Wpadłeś na heurystykę używaną przez kompilatoraby uniknąć wykładniczo złożonego wyszukiwania typów. Gdy metoda jest przeciążona, próbuje ujednoznacznić na podstawie typu argumentu. Niestety argument jest taki również przeciążony. Zamiast wypróbowywać możliwości, po prostu chwyta pierwszą, która przychodzi na myśl i nie działa.

Możesz oszukać go, szukając więcej, pytając we właściwy sposób:

g(math.max(_,_))

Notacja jest dla kompilatora jasna, że ​​szuka Function2 i to - mimo że wszystkie wersje max musi być Function2! - wystarczy, aby kompilator wyszukał dopasowanie (i pasuje Double z Double).


1 dla odpowiedzi nr 2

Kilka minut po opublikowaniu tego znalazłem to rozwiązanie:

g(math.max: ((Double, Double) => Double))

Nadal jestem ciekawy, dlaczego Scala ma problem w pierwszym przypadku.