2012-01-11 12 views
1

Следующего код показывает неглубокую иерархию, в которой тип, представляющий общую бинарную операцию используется для обоснования параметризованного абстрактного типа в другой мелкой иерархии контейнера:Переопределения выше-kinded абстрактных типов в Scala

trait BinaryOp[A] extends ((A,A) => A) 
trait Plus[A] extends BinaryOp[A] 
trait Minus[A] extends BinaryOp[A] 

trait BaseOps { 
    type T[A] <: BinaryOp[A] 
    def apply[B](one: B, two: B)(op: T[B]) = op(one, two) 
} 

case object PlusOp extends BaseOps { 
    override type T[A] = Plus[A] 
} 
case object MinusOp extends BaseOps { 
    override type T[A] = Minus[A] 
} 

object App { 
    val plus = new Plus[Int] { 
    def apply(i: Int, i2: Int) = i + i2 
    } 

    def main(a: Array[String]) { 
    val exp = Expr(PlusOp) 
    exp.bo(1,2)(plus) 
    } 
} 

Идея заключается в том чтобы иметь возможность заявить операцию, которая может быть действительной для многих разных типов спереди, без привязки к операции типа. Если я определить класс выражений в общем, все хорошо

case class Expr[T <: BaseOps](bo: T = PlusOp) 

Однако для моего случая использования нежелательно для Expr, чтобы быть paremeterized:

case class Expr(bo: BaseOps = PlusOp) 

Следующий код не без родового Expr:

object App { 
    val plus = new Plus[Int] { 
    def apply(i: Int, i2: Int) = i + i2 
    } 

    def main(a: Array[String]) { 
    val exp = Expr(PlusOp) 
    exp.bo(1,2)(plus) 
    } 
} 

ошибка:

found : App.plus.type (with underlying type java.lang.Object with Plus[Int]) 
required: exp.bo.T[Int] 
    exp.bo(1,2)(plus) 

Похоже, что информация типа от абстрактного типа T[A] <: BinaryOp[A] не подтверждается информацией в подтипе PlusOp, которая переопределяет абстрактный тип как T[A] = Plus[A]. Есть ли способ обойти это без создания Expr generic?

ответ

1

С "-Ydependent-метод-типа",

def Expr(_bo: BaseOps = PlusOp) = new BaseOps { 
    override type T[A] = _bo.T[A] 
    val bo: _bo.type = _bo 
} 

Но, я не знаю, что это точно значит ...

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