5

consideri questo frammento semplificata di alcune unità di funzionalità di misura in Scala:Perché la ricerca implicita è influenzata da un parametro di tipo non correlato?

object UnitsEx { 
    case class Quantity[M <: MInt, T: Numeric](value: T) { 
    private val num = implicitly[Numeric[T]] 
    def *[M2 <: MInt](m: Quantity[M2, T]) = 
     Quantity[M, T](num.times(value, m.value)) 
    } 

    implicit def measure[T: Numeric](v: T): Quantity[_0, T] = Quantity[_0, T](v) 
    implicit def numericToQuantity[T: Numeric](v: T): QuantityConstructor[T] = 
    new QuantityConstructor[T](v) 

    class QuantityConstructor[T: Numeric](v: T) { 
    def m = Quantity[_1, T](v) 
    } 

    sealed trait MInt 
    final class _0 extends MInt 
    final class _1 extends MInt 
} 

Questo frammento di codice mostra l'utilizzo e l'errore del compilatore ottengo attualmente:

import UnitsEx._ 

(1 m) * 1 // Works 
1 * (1 m) // Doesn't work: 
/* 
<console>:1: error: overloaded method value * with alternatives: 
(x: Double)Double <and> 
(x: Float)Float <and> 
(x: Long)Long <and> 
(x: Int)Int <and> 
(x: Char)Int <and> 
(x: Short)Int <and> 
(x: Byte)Int 
cannot be applied to (UnitsEx.Quantity[UnitsEx._1,Int]) 
1 * (1 m) 
^ 
*/ 

Avvolgere la 1 con measure sarebbe risolvere il problema, ma perché non è implicito lo scope applicato?

Se rimuovo il parametro di tipo M come nel prossimo frammento di esso inizia a lavorare, anche se non riesco a vedere come questo tipo di parametro è legato alla ricerca implicita:

object UnitsEx2 { 
    case class Quantity[T: Numeric](value: T) { 
    private val num = implicitly[Numeric[T]] 
    def *(m: Quantity[T]) = Quantity[T](num.times(value, m.value)) 
    } 

    implicit def measure[T: Numeric](v: T): Quantity[T] = Quantity[T](v) 
    implicit def numericToQuantity[T: Numeric](v: T): QuantityConstructor[T] = 
    new QuantityConstructor[T](v) 

    class QuantityConstructor[T: Numeric](v: T) { 
    def m = Quantity[T](v) 
    } 
} 

È questo atteso o una limitazione nota del correttore di tipo?

+0

Una domanda simile a cui non è stata data una risposta completa: http://stackoverflow.com/questions/7649517/why-is-the-implicit-conversion-non-considered-in-question-con-generic-paramete/ 7650605 # 7650605 –

+0

Ouch ... Ho completamente dimenticato di aver fatto quella domanda. : -/ – soc

+0

È ancora una buona domanda. –

risposta

1

Se si rinomina l'operatore * ad es. mult quindi 1 mult (1 m) funziona in entrambi i casi. Questo non risponde alla tua domanda, ma suggerisce che forse c'è qualche interferenza con l'operatore * fortemente sovraccarico.

Problemi correlati