2016-05-01 10 views
1

Meine Anforderung ist Mixin Merkmal abhängig von den Typ Parameter des generischen Typs. Dazu übergeben ich TypeTag als impliziter Parameter in der Methode apply, um den generischen Typ abzurufen.Mixin Merkmal in einer anwendungsspezifischen Option abhängig vom Typ Parameter

Dies führt zu einem folgenden Kompilierung Fehlern in der Karte Methode:

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 

Bitte legen nahe, was ich mit diesem Ansatz falsch machte, und wenn dieser Ansatz nicht für meine Anforderung passen wird. Neue Vorschläge sind willkommen und werden geschätzt.

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 
} 

Antwort

0

Bitte empfehlen, was ich mit diesem Ansatz

falsch tue Wenn Sie apply[A](value: A) benötigen eine implizite TypeTag zu haben, müssen Sie sicherstellen, dass Ihr map[B] hat die gleiche Anforderung:

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

Als map wird apply anrufen und benötigt die TypeTag zur Verfügung stehen.

+0

Wie TypeTag für den Typparameter B übergeben wird – mogli

+0

Wie ich. 'map [B: TypTag]'. –