My requirement is to mixin trait depending on the type parameter of generic type. For this I am passing TypeTag as implicit parameter in apply method to fetch the Generic type.
This results in a following compile time error in map method :
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
Please suggest, what I am doing wrong with this approach, and if this approach is not fit for my requirement. New suggetions are welcome and will be appreciated.
Simplified code:
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
}