Case class companion object generation error for compound type
Asked Answered
G

2

10

Defined empty trait Test:

trait Test

what used in compound type:

scala> val a : Int with Test = 10.asInstanceOf[Int with Test]
a: Int with Test = 10

and case class with parameter of compound type (like Unboxed Tagged Type):

scala> case class Foo(a: Int with Test)
error: type mismatch;
 found   : Double
 required: AnyRef
Note: an implicit exists from scala.Double => java.lang.Double, but
methods inherited from Object are rendered ambiguous.  This is to avoid
a blanket implicit which would convert any scala.Double to any AnyRef.
You may wish to use a type ascription: `x: java.lang.Double`.

But it is perfectly work for:

scala> case class Foo(a: List[Int] with Test)
defined class Foo

And no problem with method definition:

scala> def foo(a: Int with Test) = ???
foo: (a: Int with Test)Nothing

Scala version 2.10.3

Is it normal compiler behaviour?

Gond answered 20/11, 2013 at 11:28 Comment(1)
This is a known issue.Dow
N
5

You've bumped into one of the cases where Scala's attempt to unify primitives and Objects breaks down. Since Int in Scala represents the Java primitive type int, it can't have any traits mixed into it. When doing asInstanceOf, the Scala compiler autoboxes the Int into a java.lang.Integer:

scala> val a: Int with Test = 10.asInstanceOf[Int with Test] 
a: Int with Test = 10

scala> a.getClass
res1: Class[_ <: Int] = class java.lang.Integer

However, autoboxing doesn't happen when declaring types, so you have to do it by hand:

scala> case class Foo(x: Integer with Test)
defined class Foo

But then the compiler type checker won't autobox before checking the types:

scala> Foo(a)
<console>:12: error: type mismatch;
 found   : Int with Test
 required: Integer with Test
              Foo(a)
                  ^

So you would have to declare your variable as Integer with Test:

scala> val a: Integer with Test = 10.asInstanceOf[Integer with Test]
a: Integer with Test = 10

scala> Foo(a)
res3: Foo = Foo(10)

or use a cast when calling the case class:

val a : Int with Test = 10.asInstanceOf[Int with Test]
scala> a: Int with Test = 10

scala> Foo(a.asInstanceOf[Integer with Test])
res0: Foo = Foo(10)
Noh answered 22/1, 2014 at 14:32 Comment(1)
Since Int in Scala represents the Java primitive type int Not true. Scala uses a mixture of int and Integer for Int, with auto boxing and unboxing. It does not translate directly to int or Integer. As in the comment pointed out, it’s simply a bug in 2.10Danu
D
2

as @Travis Brown said This is a know issue,fixed in scala 2.11.7.

run under ammonite Repl 2.0.4 (scala 2.12.10 java 1.8.0_242)

@case class Foo(a: Int with Test)
a: Int with Test = 10
Driggers answered 19/4, 2020 at 13:22 Comment(1)
You should explain more about your solution.Turnstone

© 2022 - 2024 — McMap. All rights reserved.