2009-03-27 15 views
14

Quiero escribir una función que funcione en cualquier tipo de Scala con un total de pedidos (es decir, puedo usar '<' en él). ¿Cuál es la sintaxis para eso? El mejor que he llegado con es¿Cuál es la sintaxis de Scala para una función que toma cualquier subtipo de Ordenado [A]?

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

eso no funciona, sin embargo, cuando intento usarlo desde el 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)) 

Esencialmente, creo que quiero que el equivalente de esta Código Haskell:

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

Estoy usando scala 2.7.3 en un sistema Debian.

¿Qué me estoy perdiendo y dónde?

Respuesta

24

El equivalente de las clases de tipos de Haskell en Scala se realiza a través de implicits. Hay dos maneras de hacer lo que quiere

La primera es la visión límites

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 

La segunda es con un parámetro implícito

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 

El primero es el azúcar sintaxis de la tarde. El último permite más flexibilidad.

+0

¿Por qué tiene que incluir explícitamente lo implícito como parámetro del método? Si el Scala-Runtime sabe cómo convertir implícitamente T en Ordenado [T], ¿por qué necesito enumerar un parámetro implícito? ¡Gracias! – shj

+2

En primer lugar, no puede convertir cualquier T en un Pedido [T]. Por ejemplo, defina un orden sobre (Int => Int). En segundo lugar, cuando la conversión es posible, el tiempo de ejecución no sabe cómo convertir. En cambio, el compilador sabe cómo insertar una función para hacer la conversión en tiempo de ejecución. –

+0

parece que el primer método está en desuso [SI-7629] (https://issues.scala-lang.org/browse/SI-7629) –

Cuestiones relacionadas