2016-11-10 10 views
0

Я пытаюсь построить интерпретатор для моего ADT, но я не знаю, как решить проблему загрузки неявных манифестов хорошим способомКак загрузить неявный манифест из полиморфного поля типа

sealed trait Polymorphic[T] 
case class Type1[T: Manifest](field1: T) extends Polymorphic[T] 
case class Type2[T: Manifest, V: Manifest](field1: T, field2:V) extends Polymorphic[T] { 
    def vManifest: Manifest[V] = manifest[V] 
} 

object Interpreter { 
    def eval[T: Manifest](polymorphic: Polymorphic[T]): T = { 
     polymorphic match { 
     case Type1(field) => 
      ??? 
     case value: Type2[T, _] => 
      implicit val vManifest = value.vManifest 
      evalType2(value) 
     } 
    } 

    def evalType2[T:Manifest, V:Manifest](type2: Type2[T,V]): T = ??? 
} 

Этих было лучшим решением, которое я мог бы создать, но мне не нравится, что мне пришлось создать эту функцию vManifest, чтобы иметь возможность загружать манифест в eval.

Есть ли лучший способ сделать это?

ответ

1

Запомнить T: Manifest - это всего лишь сокращенный способ написать неявный аргумент конструктора. Если вы хотите, чтобы сделать этот аргумент виден снаружи, просто сделать это val:

case class Type1[T](field1: T)(implicit val tManifest: Manifest[T]) extends Polymorphic[T] 
case class Type2[T](field1: T, field2: V)(implicit val tManifest: Manifest[T], val vManifest: Manifest[V]) extends Polymorphic[T] 

(и, скорее всего, в эти дни, вы хотите ClassTag или TypeTag, а не Manifest).

+0

Спасибо, это сработает, но мне нужно будет неявно объявить манифест в контексте снова, есть ли способ избежать этого? – Mikel

+0

'import value.vManifest' будет делать то же самое. –