- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
can't create case classes for tagged types
Mon, 2011-12-05, 06:47
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
Mon, 2011-12-05, 08:27
#2
Re: can't create case classes for tagged types
body p { margin-bottom: 0cm; margin-top: 0pt; }
Sciss 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:
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
Mon, 2011-12-05, 08:27
#3
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
>>>
>>>
>>>
>
Mon, 2011-12-05, 08:37
#4
Re: can't create case classes for tagged types
body p { margin-bottom: 0cm; margin-top: 0pt; }
Sciss wrote:
Thanks
Ittay
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,
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
Mon, 2011-12-05, 08:57
#5
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,
Cheers,
Miles
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
>
>