- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
by-name and erasure
Wed, 2011-12-07, 14:21
Hi,
Someone has probably already noticed this, but by-name parameters make it hard to overload defs.
def foo(x: => Int): Stringdef foo(x: => Long): String
These two won't compile with a "same type after erasure" message. I understand why, but it is a bit of a shame. Are there any workarounds?
Matthew
--
Dr Matthew PocockIntegrative Bioinformatics Group, School of Computing Science, Newcastle Universitymailto: turingatemyhamster@gmail.com gchat: turingatemyhamster@gmail.commsn: matthew_pocock@yahoo.co.uk irc.freenode.net: drdozerskype: matthew.pococktel: (0191) 2566550mob: +447535664143
Someone has probably already noticed this, but by-name parameters make it hard to overload defs.
def foo(x: => Int): Stringdef foo(x: => Long): String
These two won't compile with a "same type after erasure" message. I understand why, but it is a bit of a shame. Are there any workarounds?
Matthew
--
Dr Matthew PocockIntegrative Bioinformatics Group, School of Computing Science, Newcastle Universitymailto: turingatemyhamster@gmail.com gchat: turingatemyhamster@gmail.commsn: matthew_pocock@yahoo.co.uk irc.freenode.net: drdozerskype: matthew.pococktel: (0191) 2566550mob: +447535664143
Wed, 2011-12-07, 17:01
#2
Re: by-name and erasure
Can you define two traits ByNameInt and ByNameLong?
trait ByNameInt {
def compute: Int}
and
object ByNameInt{
implicit def fromInt (i : => Int) = new ByNameInt{def compute = i}
}
I have never tried that though. So maybe it is totally wrong.
Best,
Nicolas.
Wed, 2011-12-07, 17:11
#3
Re: by-name and erasure
Or
trait DoFoo[T] {
def doIt(t: T): String
}
def foo[T: DoFoo](i: => T) = implicitly[DoFoo[T]].doIt(i)
And provide DoFoo[Int] and DoFoo[Long] ?
On Wed, Dec 7, 2011 at 4:51 PM, nicolas.oury@gmail.com <nicolas.oury@gmail.com> wrote:
--
Viktor Klang
Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts
Twitter: @viktorklang
trait DoFoo[T] {
def doIt(t: T): String
}
def foo[T: DoFoo](i: => T) = implicitly[DoFoo[T]].doIt(i)
And provide DoFoo[Int] and DoFoo[Long] ?
On Wed, Dec 7, 2011 at 4:51 PM, nicolas.oury@gmail.com <nicolas.oury@gmail.com> wrote:
Can you define two traits ByNameInt and ByNameLong?
trait ByNameInt {
def compute: Int}
and
object ByNameInt{
implicit def fromInt (i : => Int) = new ByNameInt{def compute = i}
}
I have never tried that though. So maybe it is totally wrong.
Best,
Nicolas.
--
Viktor Klang
Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts
Twitter: @viktorklang
Wed, 2011-12-07, 17:21
#4
Re: by-name and erasure
> And provide DoFoo[Int] and DoFoo[Long] ?
I would believe that those two has the same erasure.
Do you use specialisation to solve that?
Wed, 2011-12-07, 17:51
#5
Re: by-name and erasure
2011/12/7 nicolas.oury@gmail.com <nicolas.oury@gmail.com>
> And provide DoFoo[Int] and DoFoo[Long] ?
scala> trait DoFoo[T] {
| def doIt(t: T): String
| }
defined trait DoFoo
scala>
scala> def foo[T: DoFoo](i: => T) = implicitly[DoFoo[T]].doIt(i)
foo: [T](i: => T)(implicit evidence$1: DoFoo[T])String
scala>
scala> implicit object IntDoFoo extends DoFoo[Int] {
| override def doIt(t: Int) = "int[" + t + "]"
| }
defined module IntDoFoo
scala>
scala> implicit object LongDoFoo extends DoFoo[Long] {
| override def doIt(t: Long) = "int[" + t + "]"
| }
defined module LongDoFoo
scala>
scala> foo(1L)
res3: String = int[1]
scala> foo(1)
res4: String = int[1]
scala> foo("string")
<console>:16: error: could not find implicit value for evidence parameter of type DoFoo[java.lang.String]
foo("string")
I would believe that those two has the same erasure.
Do you use specialisation to solve that?
--
Viktor Klang
Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts
Twitter: @viktorklang
Fri, 2011-12-09, 01:01
#6
Re: by-name and erasure
2011/12/7 nicolas.oury@gmail.com <nicolas.oury@gmail.com>
> And provide DoFoo[Int] and DoFoo[Long] ?
I would believe that those two has the same erasure.
Do you use specialisation to solve that?
They may have the same erasure, but the point is that the compiler statically inserts a call to the correct implicit conversion. For that reason the correct conversion must be determinable at compile time.
For instanceval x: Any = if(math.random>.5) 1 else 1Lf(x)
won't work, since although the runtime type is either Int or Long in any given run, the compile-time type is Any.
(You asked for a workaround :-)
On Wed, Dec 7, 2011 at 7:21 AM, Matthew Pocock <turingatemyhamster@gmail.com> wrote: