Pytanie Jaka jest składnia Scali dla funkcji przyjmującej dowolny podtyp Zlecenia [A]?


Chcę napisać funkcję, która działa na dowolnym typie Scala z całkowitym uporządkowaniem (tzn. Mogę użyć "<" na nim). Jaka jest to składnia? Najlepsze, co wymyśliłem, to

def lessThan[T <: Ordered[T]](x: T, Y: T) = x < y

To jednak nie działa, gdy próbuję go używać z REPL:

scala> lessThan(1, 2)
<console>:8: error: inferred type arguments [Int] do not conform to method lessThan's type parameter bounds [T <: Ordered[T]]
       lessThan(1, 2)
       ^

scala> import runtime._
import runtime._

scala> lessThan(new RichInt(1), new RichInt(2))
<console>:8: error: inferred type arguments [scala.runtime.RichInt] do not conform to method lessThan's type parameter bounds [T <: Ordered[T]]
       lessThan(new RichInt(1), new RichInt(2))

Zasadniczo, myślę, że chcę odpowiednik tego kodu Haskella:

lessThan :: (Ord a) => a -> a -> Bool
lessThan x y = x < y

Używam scala 2.7.3 na systemie Debian.

Czego mi brakuje i gdzie?


14
2018-03-27 20:58


pochodzenie




Odpowiedzi:


Odpowiednik klas typu Haskella w Scali odbywa się za pośrednictwem implikacji. Istnieją dwa sposoby robienia tego, co chcesz

Pierwszy z widokami

scala> def lessThan[T <% Ordered[T]](x : T, y : T) = x < y
lessThan: [T](T,T)(implicit (T) => Ordered[T])Boolean

scala> lessThan(1,2)
res0: Boolean = true

Drugi to z niejawnym parametrem

scala> def lessThan[T](x : T, y : T)(implicit f : T => Ordered[T]) = x < y      
lessThan: [T](T,T)(implicit (T) => Ordered[T])Boolean

scala> lessThan(4,3)
res1: Boolean = false

Ten pierwszy to cukier składniowy na późniejszy. Później pozwala na większą elastyczność.


24
2018-03-27 22:21



Dlaczego musisz domyślnie wprowadzić implicite jako parametr do metody? Jeśli scala-runtime wie, w jaki sposób niejawnie przekonwertować T na uporządkowane [T], dlaczego muszę podać niejawny parametr? Dzięki! - shj
Po pierwsze, nie możesz po prostu przekształcić żadnego T na zamówione [T]. Na przykład zdefiniuj kolejność (Int => Int). Po drugie, gdy konwersja jest możliwa, środowisko wykonawcze nie wie, jak konwertować. Zamiast tego kompilator wie, jak wstawić funkcję do konwersji w czasie wykonywania. - James Iry
wygląda na to, że pierwsza metoda jest przestarzała SI-7629 - Juh_