mixin trait在特定于应用程序的选项中取决于类型参数

时间:2016-05-01 18:08:19

标签: scala generics apply mixins traits

我的要求是根据泛型类型的类型参数混合特性。 为此,我将 TypeTag作为apply方法中的隐式参数传递以获取Generic类型。

这导致map方法中出现以下编译时错误:

not enough arguments for method apply:
(implicit tag: reflect.runtime.universe.TypeTag[B])customOption.AppOption[B] in object AppOption.

Unspecified value parameter tag.
No TypeTag available for B

请建议,我对这种方法做错了,以及这种方法是否符合我的要求。我们欢迎新的建议,并将不胜感激。

简化代码:

package customOption.withGenericMixins

import scala.reflect.runtime.universe._

sealed abstract class AppOption[+A] {
  def value: A
  def isEmpty: Boolean

  def map[B]( f: A => B ): AppOption[B] = {
    if ( !isEmpty ) {
      println( "map called : " + value )
    }

    //compile time error
    //not enough arguments for method apply: (implicit tag: reflect.runtime.universe.TypeTag[B])customOption.AppOption[B] in object AppOption.
    //Unspecified value parameter tag.
    //No TypeTag available for B
    if ( !isEmpty ) AppOption( f( this.value ) ) else AppOptionNone
  }
  def flatMap[B]( f: A => AppOption[B] ): AppOption[B] = {
    if ( !isEmpty ) {
      println( "flatMap called : " + value )
    }
    if ( !isEmpty ) f( this.value ) else AppOptionNone
  }
}

object AppOption {
  def apply[A]( value: A )( implicit tag: TypeTag[A] ): AppOption[A] = {
    if ( value == null ) {
      AppOptionNone
    } else {
      //Depending on the type, my requirement is to mixin Traits
      val genType = tag.tpe.toString
      genType match {
        case "String"  => new AppOptionSome( value ) //with XTrait
        case "Boolean" => new AppOptionSome( value ) //with YTrait
        case "Double"  => new AppOptionSome( value ) //with ZTrait
        case _         => throw new RuntimeException( s"$genType not supported by AppOption" )
      }

    }
  }
}

case class AppOptionSome[+A]( value: A ) extends AppOption[A] {
  def isEmpty = false
}

case object AppOptionNone extends AppOption[Nothing] {

  def value = throw new NoSuchElementException( "AppOptionNone.value" )
  def isEmpty = true
}

1 个答案:

答案 0 :(得分:0)

  

请建议我采用这种方法做错了

如果您需要apply[A](value: A)隐含TypeTag,则需要确保map[B]具有相同的要求:

def map[B: TypeTag](f: A => B): AppOption[B]

由于map会致电apply,并且需要提供所述TypeTag