2015-09-16 4 views
2

У меня есть следующие черты (упрощенный пример)Параметризованные оценки типа

trait F[A, M[_] <: Option[A]] { 

    def v: A 

    def f: A => M[A] 

} 

Я хочу, чтобы иметь возможность создать такую ​​черту

trait G[A] extends F[A, Some] 

Но это дает следующее сообщение об ошибке

Error:(18, 20) type arguments [A,Some] do not conform to trait F's type parameter bounds [A,M[_] <: Option[A]]

Как я могу связать пункт M[_] измерительный тип?

Edit:

F[A, M[_] <: Option[_]] тип будет работать. Но я на самом деле есть еще одна функция в моей черты

trait F[A, M[_] <: Option[_]] { 

    def v: A 

    def f: A => M[A] 

    def f2: A => A = { 
    (a: A) => f(a).get 
    } 

} 

И в этом случае в f2, get не возвращает значение типа A, даже если f возвращает M[A]

Error:(17, 20) type mismatch; 
found : _$1 
required: A 
    (a: A) => f(a).get 
+0

Можете ли вы просто сменить M [_] на M [A]? –

+0

Спасибо, Rich, изменение 'M [_]' на 'M [A]' фактически работает. – synapski

ответ

0

Вы можете полностью ограничить тип M, так как он на самом деле не нужно принимать параметры типа:

trait F[A, M <: Option[A]] { // M no longer takes a type parameter 
    def v: A 
    def f: A => M 
    } 

    trait G[A] extends F[A, Some[A]] // Must specify M[A] since M doesn't take a type parameter 

Однако вы можете предоставить какой-то механизм отображения или что-то и идти в какой-то другой тип M[B] в этом случае менее сдержан версия будет работать лучше:

trait F[A, M[_] <: Option[_]] { // M is no longer constrained to A 
    def v: A 
    def f: A => M[A] // M is manually constrained to A here 
    } 

    trait G[A] extends F[A, Some] 

UPDATE

К сожалению, ваш f2 функция не будет работать. Несмотря на то, что знает, что типы верны, компилятор не может правильно определить тип (ограничения Scala). Вы можете добавить эту функцию в G[A], и она будет работать должным образом, потому что у M[_] теперь есть конкретный тип.

trait G[A] extends F[A, Some]{ 
    def f3: A => A = a => f(a).get 
    } 

И как примечание стороны, вы никогда не должны использовать Option.get, что поражения цели с помощью Option! flatMap это или что-то :)

+0

Спасибо, Ноа. Я отредактировал вопрос в соответствии с моим вариантом использования. 'F [A, M [_] <: Option [_]]' это то, что я хочу, но я не могу получить правильный тип в своей новой функции. – synapski

+0

@synapski обновил ответ – Noah

Смежные вопросы