2015-07-15 2 views
5

Это не тип:Тип вывода и модель Maching в Scala

sealed trait BinOp[-InA, -InB, +Out] 
case object Add extends BinOp[Int, Int, Int] 

sealed trait Expression[+A] 
final case class IntegerAtom(value: Int) extends Expression[Int] 
final case class BinaryExp[-A, -B, +C](op: BinOp[A, B, C], lhs: Expression[A], rhs: Expression[B]) extends Expression[C] 

def optimizeStep[A](x: Expression[A]): Expression[A] = x match { 
    case BinaryExp(Add, IntegerAtom(a), IntegerAtom(b)) => IntegerAtom(a + b) 
} 

Самое непосредственное, что является использование в случае объекта в шаблоне сопоставляются:

[error] (...) pattern type is incompatible with expected type; 
[error] found : minimumexample.Add.type 
[error] required: minimumexample.BinOp[Any,Any,A] 

кажется, что это может быть решена путем введения глазной кровотечение:

val AddOp = Add 

И потом:

case BinaryExp(AddOp, IntegerAtom(a), IntegerAtom(b)) => IntegerAtom(a + b) 

Но тогда:

[error] (...) type mismatch; 
[error] found : minimumexample.IntegerAtom 
[error] required: minimumexample.Expression[A] 
[error]  case BinaryExp(AddOp, IntegerAtom(a), IntegerAtom(b)) => IntegerAtom(a + b) 
[error]                  ^

Я хочу, чтобы решить эту проблему, как типа безопасно, насколько это возможно, не прибегая к .asInstanceOf[]. Мысли?

+0

Это минимальный (не) рабочий пример. Компилятор не понимает, что 'A' становится' Int' после соответствия шаблону. –

+0

Что я говорю, ошибки, которые я получаю при вставке этого кода в REPL, сильно отличаются от ошибок, которые вы получаете. Ошибки дисперсии вызывают последующие ошибки, о которых вы спрашиваете. –

ответ

5

Основная проблема с вашим кодом - проблема с отклонениями в определении BinaryExp, но это не похоже на вопрос. Как только вы получите исправление, вы останетесь с единственным неудобством, что case object не вводит новый тип.

Типичный шаблон для решения этой проблемы - объявить sealed trait, а затем предоставить case object для его продления.

Вот пример, который компилирует

sealed trait BinOp[-InA, -InB, +Out] 
sealed trait Add extends BinOp[Int, Int, Int] 
case object Add extends Add 

sealed trait Expression[+A] 
final case class IntegerAtom(value: Int) extends Expression[Int] 
final case class BinaryExp[A, B, C](op: BinOp[A, B, C], lhs: Expression[A], rhs: Expression[B]) extends Expression[C] 

def optimizeStep[A](x: Expression[A]): Expression[A] = x match { 
    case BinaryExp((_: Add), IntegerAtom(a), IntegerAtom(b)) => IntegerAtom(a + b) 
} 

где:

  • дисперсия "фиксированный" в наивной образом (удаление его)
  • Add в настоящее время является типов благодаря sealed trait определение
  • матч выполнен по номеру (_: Add)
+0

Я не думаю, что вам нужно '(_: Добавить)', если это всего лишь случайный объект. Так или иначе, он компилируется в моей версии. –

+4

'case object' действительно вводит новый тип; вы можете обратиться к нему с помощью 'Add.type'. –

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