Type aliases and implicit not found annotation

161 views
Skip to first unread message

Edmondo Porcu

unread,
May 16, 2013, 3:32:55 AM5/16/13
to scala...@googlegroups.com

Dear all,

 

Sometimes I alias my type on existing classes for readability, ex :

 

Type Hasher[T,K] = (T=>K)

 

And use it in class constructor as an implicit parameter.

 

Would it be possible to annotate the type with an @implicitNotFound ?

 

Thanks

 

Best Regards

 

 

Edmondo Porcu

 

 


______________________________________________________________________
This email has been scanned by the Symantec Email Security.cloud service.
For more information please visit http://www.symanteccloud.com
______________________________________________________________________

Som Snytt

unread,
May 16, 2013, 1:04:37 PM5/16/13
to Edmondo Porcu, scala...@googlegroups.com
I'm not sure what you're asking.  Annotating the type alias works as expected, so that must not be what you're asking.

If there is an existing class that takes an implicit and you want to change the not found message, the straightforward solution is to write and use a factory method that takes the alias. (pasted at bottom)

Another option is to use a custom type that exists just long enough to use the alias, then gets converted to the existing class.

If the custom type is AnyVal, then the intermediate type evaporates.  Unfortunately, value classes don't yet take multiple values, so that is not very practical.

But it's interesting to see that it performs as promised, modulo the MODULE$.


package nofunc

import scala.language.implicitConversions

package existing {
  case class Foo(implicit v: Function1[String, Int]) {
    def value(s: String): Int = v(s)
  }
  /*
  case class Foo(s: String)(implicit v: Function1[String, Int]) {
    def value: Int = v(s)
  }
  */
}
package object existing {
  def use(foo: Foo, s: String) = foo.value(s).toString
}

package object client {
  import existing._

  @annotation.implicitNotFound(msg = "Unable to convert!")
  type Converter[A,B] = A => B

  //@inline implicit def fromMyFoo(mine: MyFoo) = new Foo(mine.s)(mine.v)
  @inline implicit def fromMyFoo(mine: MyFoo) = Foo()(mine.v)
  implicit val cv: String => Int = Integer parseInt _
}
package client {
  //class MyFoo(val s: String)(implicit val v: Converter[String, Int]) /* extends AnyVal */
  class MyFoo(implicit val v: Converter[String, Int]) extends AnyVal

  object Test extends App {
    import existing._
    println(use(new MyFoo, "9"))
    //println(new MyFoo("9").value)
  }
}


scala> :javap  nofunc.client.Test$#delayedEndpoint$nofunc$client$Test$1
  public final void delayedEndpoint$nofunc$client$Test$1();
    flags: ACC_PUBLIC, ACC_FINAL
    Code:
      stack=5, locals=3, args_size=1
         0: aload_0      
         1: getstatic     #66                 // Field nofunc/existing/package$.MODULE$:Lnofunc/existing/package$;
         4: getstatic     #71                 // Field nofunc/client/package$.MODULE$:Lnofunc/client/package$;
         7: getstatic     #71                 // Field nofunc/client/package$.MODULE$:Lnofunc/client/package$;
        10: invokevirtual #75                 // Method nofunc/client/package$.cv:()Lscala/Function1;
        13: astore_2     
        14: astore_1     
        15: new           #77                 // class nofunc/existing/Foo
        18: dup          
        19: aload_2      
        20: invokespecial #80                 // Method nofunc/existing/Foo."<init>":(Lscala/Function1;)V


package nofunc

import scala.language.implicitConversions

package existing {
  case class Foo(s: String)(implicit v: Function1[String, Int]) {
    def value: Int = v(s)
  }
}

package object client {
  import existing._

  @annotation.implicitNotFound(msg = "Unable to convert!")
  type Converter[A,B] = A => B

  type Foo = existing.Foo
  object Foo {
    def apply(s: String)(implicit v: Converter[String, Int]) =
      existing.Foo(s)(v)
  }

  //implicit val cv: String => Int = Integer parseInt _
}
package client {
  object Test extends App {
    val f: Foo = Foo("9")
    println(f.value)
  }
}





--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages