Каков синтаксис Scala для функции, принимающей любой подтип Ordered[A]?

Я хочу написать функцию, которая работает с любым типом Scala с полным порядком (т. е. я могу использовать для нее '‹'). Какой синтаксис для этого? Лучшее, что я придумал, это

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

Однако это не работает, когда я пытаюсь использовать его из 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))

По сути, я считаю, что мне нужен эквивалент этого кода Haskell:

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

Я использую scala 2.7.3 в системе Debian.

Что я упускаю и где?


person asciiphil    schedule 27.03.2009    source источник


Ответы (1)


Эквивалент классов типов Haskell в Scala выполняется с помощью неявных. Есть два способа сделать то, что вы хотите

Первый с границами просмотра

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

Второй с неявным параметром

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

Первый — синтаксический сахар для второго. Последнее обеспечивает большую гибкость.

person James Iry    schedule 27.03.2009
comment
Почему вы должны явно указывать неявное в качестве параметра метода? Если среда выполнения scala знает, как неявно преобразовать T в Ordered[T], зачем мне указывать неявный параметр? Спасибо! - person shj; 09.01.2011
comment
Во-первых, вы не можете просто преобразовать любой T в Ordered[T]. Например, определите порядок (Int => Int). Во-вторых, когда преобразование возможно, среда выполнения не знает, как выполнить преобразование. Вместо этого компилятор знает, как вставить функцию для выполнения преобразования во время выполнения. - person James Iry; 10.01.2011
comment
похоже, что первый метод устарел SI-7629 - person Juh_; 08.12.2015