This page is no longer maintained — Please continue to the home page at www.scala-lang.org

can't create case classes for tagged types

5 replies
Ittay Dror 2
Joined: 2010-05-05,
User offline. Last seen 42 years 45 weeks ago.
body p { margin-bottom: 0cm; margin-top: 0pt; }

scala> trait Millis
defined trait Millis

scala> case class Foo(l: Long with Millis)
<console>:8: error: ambiguous reference to overloaded definition,
both method == in class Object of type (x$1: AnyRef)Boolean
and  method == in class Long of type (x: Long)Boolean
match argument types (Long with Millis) and expected result type Boolean
       case class Foo(l: Long with Millis)
                  ^

I can work around this by using java.lang.Long, but want to know if there is another alternative.

Regards,

Ittay


Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.
Re: can't create case classes for tagged types

see 'unboxed tagged types' recently discovered:

https://gist.github.com/89c9b47a91017973a35f
http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagge...

if Millis is really just a marker trait, you should be able to use Long @@ Millis

best, -sciss-

On 5 Dec 2011, at 05:43, Ittay Dror wrote:

> scala> trait Millis
> defined trait Millis
>
> scala> case class Foo(l: Long with Millis)
> :8: error: ambiguous reference to overloaded definition,
> both method == in class Object of type (x$1: AnyRef)Boolean
> and method == in class Long of type (x: Long)Boolean
> match argument types (Long with Millis) and expected result type Boolean
> case class Foo(l: Long with Millis)
> ^
> I can work around this by using java.lang.Long, but want to know if there is another alternative.
> Regards,
> Ittay
>
>

Ittay Dror 2
Joined: 2010-05-05,
User offline. Last seen 42 years 45 weeks ago.
Re: can't create case classes for tagged types
body p { margin-bottom: 0cm; margin-top: 0pt; }

I am using it. The problem is that Long @@ Millis extends both Long and Tagged. Both have a '==' method. I can't figure out how to disambiguate (without resulting to writing a simple class)


Sciss wrote:
584B348D-220A-4817-9B7B-E66CF0338E34 [at] sciss [dot] de" type="cite">
see 'unboxed tagged types' recently discovered:

https://gist.github.com/89c9b47a91017973a35f
http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagged-types.html

if Millis is really just a marker trait, you should be able to use Long @@ Millis

best, -sciss-


On 5 Dec 2011, at 05:43, Ittay Dror wrote:

scala> trait Millis
defined trait Millis

scala> case class Foo(l: Long with Millis)
<console>:8: error: ambiguous reference to overloaded definition,
both method == in class Object of type (x$1: AnyRef)Boolean
and  method == in class Long of type (x: Long)Boolean
match argument types (Long with Millis) and expected result type Boolean
       case class Foo(l: Long with Millis)
                  ^
I can work around this by using java.lang.Long, but want to know if there is another alternative.
Regards,
Ittay



    
Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.
Re: can't create case classes for tagged types

oh i see, that didn't work either.

it seems there is a problem with the case class synthetisation process. if you override `equals`, it seems to be working:

type Tagged[U] = { type Tag = U }
type @@[T, U] = T with Tagged[U]

def tag[U](l : Long) : Long @@ U = l.asInstanceOf[Long @@ U]

trait Millis

case class Foo( l: Long @@ Millis ) {
final def canEqual( x: Any ) : Boolean = x.isInstanceOf[ Foo ]
override def equals( x: Any ) : Boolean = (this eq x.asInstanceOf[ AnyRef ]) || (x match {
case f: Foo if( (f.l: Long) == (l: Long) && f.canEqual( this )) => true
case _ => false
})
}

Foo( tag[ Millis ]( 33L )) == Foo( tag[ Millis ]( 34L )) // false
Foo( tag[ Millis ]( 33L )) == Foo( tag[ Millis ]( 33L )) // true

On 5 Dec 2011, at 07:12, Ittay Dror wrote:

> I am using it. The problem is that Long @@ Millis extends both Long and Tagged. Both have a '==' method. I can't figure out how to disambiguate (without resulting to writing a simple class)
>
> Sciss wrote:
>> see 'unboxed tagged types' recently discovered:
>>
>>
>> https://gist.github.com/89c9b47a91017973a35f
>> http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagge...
>>
>>
>> if Millis is really just a marker trait, you should be able to use Long @@ Millis
>>
>> best, -sciss-
>>
>>
>> On 5 Dec 2011, at 05:43, Ittay Dror wrote:
>>
>>
>>> scala> trait Millis
>>> defined trait Millis
>>>
>>> scala> case class Foo(l: Long with Millis)
>>> :8: error: ambiguous reference to overloaded definition,
>>> both method == in class Object of type (x$1: AnyRef)Boolean
>>> and method == in class Long of type (x: Long)Boolean
>>> match argument types (Long with Millis) and expected result type Boolean
>>> case class Foo(l: Long with Millis)
>>> ^
>>> I can work around this by using java.lang.Long, but want to know if there is another alternative.
>>> Regards,
>>> Ittay
>>>
>>>
>>>
>

Ittay Dror 2
Joined: 2010-05-05,
User offline. Last seen 42 years 45 weeks ago.
Re: can't create case classes for tagged types
body p { margin-bottom: 0cm; margin-top: 0pt; }
Sciss wrote:
890036A2-799A-4FB0-856E-FDB757B67C08 [at] sciss [dot] de" type="cite">
oh i see, that didn't work either. 

it seems there is a problem with the case class synthetisation process. if you override `equals`, it seems to be working:

Arghh,


I did try it, but defined equals to take a Foo, not Any...

Thanks
Ittay
890036A2-799A-4FB0-856E-FDB757B67C08 [at] sciss [dot] de" type="cite">

type Tagged[U] = { type Tag = U }
type @@[T, U] = T with Tagged[U]
  
def tag[U](l : Long) : Long @@ U = l.asInstanceOf[Long @@ U]

trait Millis

case class Foo( l: Long @@ Millis ) {
   final def canEqual( x: Any ) : Boolean = x.isInstanceOf[ Foo ]
   override def equals( x: Any ) : Boolean = (this eq x.asInstanceOf[ AnyRef ]) || (x match {
     case f: Foo if( (f.l: Long) == (l: Long) && f.canEqual( this )) => true
     case _ => false
    })
}

Foo( tag[ Millis ]( 33L )) == Foo( tag[ Millis ]( 34L )) // false
Foo( tag[ Millis ]( 33L )) == Foo( tag[ Millis ]( 33L )) // true



On 5 Dec 2011, at 07:12, Ittay Dror wrote:

I am using it. The problem is that Long @@ Millis extends both Long and Tagged. Both have a '==' method. I can't figure out how to disambiguate (without resulting to writing a simple class)

Sciss wrote:
see 'unboxed tagged types' recently discovered:


https://gist.github.com/89c9b47a91017973a35f
http://etorreborre.blogspot.com/2011/11/practical-uses-for-unboxed-tagged-types.html


if Millis is really just a marker trait, you should be able to use Long @@ Millis

best, -sciss-


On 5 Dec 2011, at 05:43, Ittay Dror wrote:


scala> trait Millis
defined trait Millis

scala> case class Foo(l: Long with Millis)
<console>:8: error: ambiguous reference to overloaded definition,
both method == in class Object of type (x$1: AnyRef)Boolean
and  method == in class Long of type (x: Long)Boolean
match argument types (Long with Millis) and expected result type Boolean
       case class Foo(l: Long with Millis)
                  ^
I can work around this by using java.lang.Long, but want to know if there is another alternative.
Regards,
Ittay




      

    
milessabin
Joined: 2008-08-11,
User offline. Last seen 33 weeks 3 days ago.
Re: can't create case classes for tagged types

On Mon, Dec 5, 2011 at 7:18 AM, Sciss wrote:
> oh i see, that didn't work either.
>
> it seems there is a problem with the case class synthetisation process.

Yup, see here,

http://goo.gl/EP48o

Cheers,

Miles

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland