2009-03-27 16 views
14

Voglio scrivere una funzione che funziona su qualsiasi tipo di Scala con un ordinamento totale (ad esempio, posso usare '<' su di esso). Qual è la sintassi per questo? Il migliore che è venuta in mente èQual è la sintassi di Scala per una funzione che accetta qualsiasi sottotipo di Ordinato [A]?

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

che non funziona, però, quando provo ad usarlo dal 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)) 

In sostanza, credo che voglio l'equivalente di questo Codice Haskell:

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

Sto usando scala 2.7.3 su un sistema Debian.

Cosa mi manca e dove?

risposta

24

L'equivalente delle classi di tipi di Haskell in Scala viene eseguito tramite impliciti. Ci sono due modi per fare ciò che si vuole

Il primo è con vista limiti

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 

Il secondo è con un parametro implicito

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 

L'ex è lo zucchero sintassi per la successiva. Più tardi consente una maggiore flessibilità.

+0

Perché devi implicare esplicitamente il parametro implicito nel metodo? Se scala-runtime sa come convertire implicitamente T in Ordered [T] perché devo elencare un parametro implicito? Grazie! – shj

+2

Innanzitutto, non è possibile convertire qualsiasi T in Ordinato [T]. Ad esempio, definire un ordinamento su (Int => Int). In secondo luogo, quando la conversione è possibile, il runtime non sa come convertire. Invece, il compilatore sa come inserire una funzione per eseguire la conversione in fase di esecuzione. –

+0

sembra che il primo metodo sia deprecato [SI-7629] (https://issues.scala-lang.org/browse/SI-7629) –

Problemi correlati