Scala type mismatch when composing traits
up vote
0
down vote
favorite
I am trying to compute some types that I later need to refer to.
I am trying to achieve this by storing the types in type members.
Here's an example:
trait TypeClass[A] {
def op(x: A): A
}
object TypeClass {
implicit object FloatIsTypeClass extends TypeClass[Float] {
override def op(x: Float) = x
}
implicit object DoubleIsTypeClass extends TypeClass[Double] {
override def op(x: Double) = x
}
}
object TraitBounds {
trait Types1 {
type Member1
val cls1: TypeClass[Member1]
}
class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
type Member1 = A
override val cls1 = ev
}
trait Types2 {
type Member2
val cls2: TypeClass[Member2]
}
class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
type Member2 = A
override val cls2 = ev
}
trait AllTypes extends Types1 with Types2
def mk(x: Int): AllTypes = {
import TypeClass._
val (instance1, instance2) =
if (x == 1) {
(new Types1Impl[Float](), new Types2Impl[Double]())
} else {
(new Types1Impl[Double](), new Types2Impl[Float]())
}
new AllTypes {
override type Member1 = instance1.Member1
override val cls1 = instance1.cls1
override type Member2 = instance2.Member2
override val cls2 = instance2.cls2
}
}
def main(args: Array[String]): Unit = {
val in = mk(1)
println(in)
}
}
I am getting the following error:
Error:(54, 43) type mismatch;
found : TypeClass[_1]
required: TypeClass[this.Member1]
(which expands to) TypeClass[_1]
override val cls1 = instance1.cls1
It seems to me that I am expressing something that should be acceptable but for some reason the compiler does not understand what I'm trying to do (or maybe I'm wrong).
Why am I getting the type error? Is there a workaround for this?
scala generics types
add a comment |
up vote
0
down vote
favorite
I am trying to compute some types that I later need to refer to.
I am trying to achieve this by storing the types in type members.
Here's an example:
trait TypeClass[A] {
def op(x: A): A
}
object TypeClass {
implicit object FloatIsTypeClass extends TypeClass[Float] {
override def op(x: Float) = x
}
implicit object DoubleIsTypeClass extends TypeClass[Double] {
override def op(x: Double) = x
}
}
object TraitBounds {
trait Types1 {
type Member1
val cls1: TypeClass[Member1]
}
class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
type Member1 = A
override val cls1 = ev
}
trait Types2 {
type Member2
val cls2: TypeClass[Member2]
}
class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
type Member2 = A
override val cls2 = ev
}
trait AllTypes extends Types1 with Types2
def mk(x: Int): AllTypes = {
import TypeClass._
val (instance1, instance2) =
if (x == 1) {
(new Types1Impl[Float](), new Types2Impl[Double]())
} else {
(new Types1Impl[Double](), new Types2Impl[Float]())
}
new AllTypes {
override type Member1 = instance1.Member1
override val cls1 = instance1.cls1
override type Member2 = instance2.Member2
override val cls2 = instance2.cls2
}
}
def main(args: Array[String]): Unit = {
val in = mk(1)
println(in)
}
}
I am getting the following error:
Error:(54, 43) type mismatch;
found : TypeClass[_1]
required: TypeClass[this.Member1]
(which expands to) TypeClass[_1]
override val cls1 = instance1.cls1
It seems to me that I am expressing something that should be acceptable but for some reason the compiler does not understand what I'm trying to do (or maybe I'm wrong).
Why am I getting the type error? Is there a workaround for this?
scala generics types
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I am trying to compute some types that I later need to refer to.
I am trying to achieve this by storing the types in type members.
Here's an example:
trait TypeClass[A] {
def op(x: A): A
}
object TypeClass {
implicit object FloatIsTypeClass extends TypeClass[Float] {
override def op(x: Float) = x
}
implicit object DoubleIsTypeClass extends TypeClass[Double] {
override def op(x: Double) = x
}
}
object TraitBounds {
trait Types1 {
type Member1
val cls1: TypeClass[Member1]
}
class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
type Member1 = A
override val cls1 = ev
}
trait Types2 {
type Member2
val cls2: TypeClass[Member2]
}
class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
type Member2 = A
override val cls2 = ev
}
trait AllTypes extends Types1 with Types2
def mk(x: Int): AllTypes = {
import TypeClass._
val (instance1, instance2) =
if (x == 1) {
(new Types1Impl[Float](), new Types2Impl[Double]())
} else {
(new Types1Impl[Double](), new Types2Impl[Float]())
}
new AllTypes {
override type Member1 = instance1.Member1
override val cls1 = instance1.cls1
override type Member2 = instance2.Member2
override val cls2 = instance2.cls2
}
}
def main(args: Array[String]): Unit = {
val in = mk(1)
println(in)
}
}
I am getting the following error:
Error:(54, 43) type mismatch;
found : TypeClass[_1]
required: TypeClass[this.Member1]
(which expands to) TypeClass[_1]
override val cls1 = instance1.cls1
It seems to me that I am expressing something that should be acceptable but for some reason the compiler does not understand what I'm trying to do (or maybe I'm wrong).
Why am I getting the type error? Is there a workaround for this?
scala generics types
I am trying to compute some types that I later need to refer to.
I am trying to achieve this by storing the types in type members.
Here's an example:
trait TypeClass[A] {
def op(x: A): A
}
object TypeClass {
implicit object FloatIsTypeClass extends TypeClass[Float] {
override def op(x: Float) = x
}
implicit object DoubleIsTypeClass extends TypeClass[Double] {
override def op(x: Double) = x
}
}
object TraitBounds {
trait Types1 {
type Member1
val cls1: TypeClass[Member1]
}
class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
type Member1 = A
override val cls1 = ev
}
trait Types2 {
type Member2
val cls2: TypeClass[Member2]
}
class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
type Member2 = A
override val cls2 = ev
}
trait AllTypes extends Types1 with Types2
def mk(x: Int): AllTypes = {
import TypeClass._
val (instance1, instance2) =
if (x == 1) {
(new Types1Impl[Float](), new Types2Impl[Double]())
} else {
(new Types1Impl[Double](), new Types2Impl[Float]())
}
new AllTypes {
override type Member1 = instance1.Member1
override val cls1 = instance1.cls1
override type Member2 = instance2.Member2
override val cls2 = instance2.cls2
}
}
def main(args: Array[String]): Unit = {
val in = mk(1)
println(in)
}
}
I am getting the following error:
Error:(54, 43) type mismatch;
found : TypeClass[_1]
required: TypeClass[this.Member1]
(which expands to) TypeClass[_1]
override val cls1 = instance1.cls1
It seems to me that I am expressing something that should be acceptable but for some reason the compiler does not understand what I'm trying to do (or maybe I'm wrong).
Why am I getting the type error? Is there a workaround for this?
scala generics types
scala generics types
edited Nov 22 at 15:16
asked Nov 22 at 15:01
fusion
873512
873512
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
Probably there are some errors regarding the type system, especially in this line val (instance1, instance2) =
, since in one branch of the if instance1
is of type Types1Impl[Float]
and in the other is of type Types1Impl[Double]
, it may be inferred as of type Types1Impl[AnyVal]
and maybe that's what causes the problem, but I don't know too much about the compiler to know the exact reason.
However, I gave a little refactor to your code and its working for me.
trait TypeClass[A] {
def op(x: A): A
}
object TypeClass {
implicit val FloatIsTypeClass: TypeClass[Float] = new TypeClass[Float] {
override def op(x: Float): Float = x
}
implicit val DoubleIsTypeClass: TypeClass[Double] = new TypeClass[Double] {
override def op(x: Double): Double = x
}
}
object TraitBounds {
trait Types1 {
type Member1
val cls1: TypeClass[Member1]
}
object Types1 {
private class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
override type Member1 = A
override val cls1 = ev
}
def apply[A: TypeClass]: Types1 = new Types1Impl[A]
}
trait Types2 {
type Member2
val cls2: TypeClass[Member2]
}
object Types2 {
private class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
override type Member2 = A
override val cls2 = ev
}
def apply[A: TypeClass]: Types2 = new Types2Impl[A]
}
trait AllTypes extends Types1 with Types2
object AllTypes {
def fromTypes(t1: Types1, t2: Types2): AllTypes = new AllTypes {
override type Member1 = t1.Member1
override val cls1 = t1.cls1
override type Member2 = t2.Member2
override val cls2 = t2.cls2
}
}
def mk(x: Int): AllTypes =
if (x == 1) {
AllTypes.fromTypes(Types1[Float], Types2[Double])
} else {
AllTypes.fromTypes(Types1[Double], Types2[Float])
}
def main(args: Array[String]): Unit = {
val in: AllTypes = mk(1)
println(in)
}
}
A couple of notes, always prefer implicit vals
and defs
with specific type signatures over implicit objects
, they tend up to mess the type system since an object is of type ThatObjectName.type
.
Also, hide your implementations behind factory constructors to shadow their types to the parent trait
.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
Probably there are some errors regarding the type system, especially in this line val (instance1, instance2) =
, since in one branch of the if instance1
is of type Types1Impl[Float]
and in the other is of type Types1Impl[Double]
, it may be inferred as of type Types1Impl[AnyVal]
and maybe that's what causes the problem, but I don't know too much about the compiler to know the exact reason.
However, I gave a little refactor to your code and its working for me.
trait TypeClass[A] {
def op(x: A): A
}
object TypeClass {
implicit val FloatIsTypeClass: TypeClass[Float] = new TypeClass[Float] {
override def op(x: Float): Float = x
}
implicit val DoubleIsTypeClass: TypeClass[Double] = new TypeClass[Double] {
override def op(x: Double): Double = x
}
}
object TraitBounds {
trait Types1 {
type Member1
val cls1: TypeClass[Member1]
}
object Types1 {
private class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
override type Member1 = A
override val cls1 = ev
}
def apply[A: TypeClass]: Types1 = new Types1Impl[A]
}
trait Types2 {
type Member2
val cls2: TypeClass[Member2]
}
object Types2 {
private class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
override type Member2 = A
override val cls2 = ev
}
def apply[A: TypeClass]: Types2 = new Types2Impl[A]
}
trait AllTypes extends Types1 with Types2
object AllTypes {
def fromTypes(t1: Types1, t2: Types2): AllTypes = new AllTypes {
override type Member1 = t1.Member1
override val cls1 = t1.cls1
override type Member2 = t2.Member2
override val cls2 = t2.cls2
}
}
def mk(x: Int): AllTypes =
if (x == 1) {
AllTypes.fromTypes(Types1[Float], Types2[Double])
} else {
AllTypes.fromTypes(Types1[Double], Types2[Float])
}
def main(args: Array[String]): Unit = {
val in: AllTypes = mk(1)
println(in)
}
}
A couple of notes, always prefer implicit vals
and defs
with specific type signatures over implicit objects
, they tend up to mess the type system since an object is of type ThatObjectName.type
.
Also, hide your implementations behind factory constructors to shadow their types to the parent trait
.
add a comment |
up vote
2
down vote
accepted
Probably there are some errors regarding the type system, especially in this line val (instance1, instance2) =
, since in one branch of the if instance1
is of type Types1Impl[Float]
and in the other is of type Types1Impl[Double]
, it may be inferred as of type Types1Impl[AnyVal]
and maybe that's what causes the problem, but I don't know too much about the compiler to know the exact reason.
However, I gave a little refactor to your code and its working for me.
trait TypeClass[A] {
def op(x: A): A
}
object TypeClass {
implicit val FloatIsTypeClass: TypeClass[Float] = new TypeClass[Float] {
override def op(x: Float): Float = x
}
implicit val DoubleIsTypeClass: TypeClass[Double] = new TypeClass[Double] {
override def op(x: Double): Double = x
}
}
object TraitBounds {
trait Types1 {
type Member1
val cls1: TypeClass[Member1]
}
object Types1 {
private class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
override type Member1 = A
override val cls1 = ev
}
def apply[A: TypeClass]: Types1 = new Types1Impl[A]
}
trait Types2 {
type Member2
val cls2: TypeClass[Member2]
}
object Types2 {
private class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
override type Member2 = A
override val cls2 = ev
}
def apply[A: TypeClass]: Types2 = new Types2Impl[A]
}
trait AllTypes extends Types1 with Types2
object AllTypes {
def fromTypes(t1: Types1, t2: Types2): AllTypes = new AllTypes {
override type Member1 = t1.Member1
override val cls1 = t1.cls1
override type Member2 = t2.Member2
override val cls2 = t2.cls2
}
}
def mk(x: Int): AllTypes =
if (x == 1) {
AllTypes.fromTypes(Types1[Float], Types2[Double])
} else {
AllTypes.fromTypes(Types1[Double], Types2[Float])
}
def main(args: Array[String]): Unit = {
val in: AllTypes = mk(1)
println(in)
}
}
A couple of notes, always prefer implicit vals
and defs
with specific type signatures over implicit objects
, they tend up to mess the type system since an object is of type ThatObjectName.type
.
Also, hide your implementations behind factory constructors to shadow their types to the parent trait
.
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
Probably there are some errors regarding the type system, especially in this line val (instance1, instance2) =
, since in one branch of the if instance1
is of type Types1Impl[Float]
and in the other is of type Types1Impl[Double]
, it may be inferred as of type Types1Impl[AnyVal]
and maybe that's what causes the problem, but I don't know too much about the compiler to know the exact reason.
However, I gave a little refactor to your code and its working for me.
trait TypeClass[A] {
def op(x: A): A
}
object TypeClass {
implicit val FloatIsTypeClass: TypeClass[Float] = new TypeClass[Float] {
override def op(x: Float): Float = x
}
implicit val DoubleIsTypeClass: TypeClass[Double] = new TypeClass[Double] {
override def op(x: Double): Double = x
}
}
object TraitBounds {
trait Types1 {
type Member1
val cls1: TypeClass[Member1]
}
object Types1 {
private class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
override type Member1 = A
override val cls1 = ev
}
def apply[A: TypeClass]: Types1 = new Types1Impl[A]
}
trait Types2 {
type Member2
val cls2: TypeClass[Member2]
}
object Types2 {
private class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
override type Member2 = A
override val cls2 = ev
}
def apply[A: TypeClass]: Types2 = new Types2Impl[A]
}
trait AllTypes extends Types1 with Types2
object AllTypes {
def fromTypes(t1: Types1, t2: Types2): AllTypes = new AllTypes {
override type Member1 = t1.Member1
override val cls1 = t1.cls1
override type Member2 = t2.Member2
override val cls2 = t2.cls2
}
}
def mk(x: Int): AllTypes =
if (x == 1) {
AllTypes.fromTypes(Types1[Float], Types2[Double])
} else {
AllTypes.fromTypes(Types1[Double], Types2[Float])
}
def main(args: Array[String]): Unit = {
val in: AllTypes = mk(1)
println(in)
}
}
A couple of notes, always prefer implicit vals
and defs
with specific type signatures over implicit objects
, they tend up to mess the type system since an object is of type ThatObjectName.type
.
Also, hide your implementations behind factory constructors to shadow their types to the parent trait
.
Probably there are some errors regarding the type system, especially in this line val (instance1, instance2) =
, since in one branch of the if instance1
is of type Types1Impl[Float]
and in the other is of type Types1Impl[Double]
, it may be inferred as of type Types1Impl[AnyVal]
and maybe that's what causes the problem, but I don't know too much about the compiler to know the exact reason.
However, I gave a little refactor to your code and its working for me.
trait TypeClass[A] {
def op(x: A): A
}
object TypeClass {
implicit val FloatIsTypeClass: TypeClass[Float] = new TypeClass[Float] {
override def op(x: Float): Float = x
}
implicit val DoubleIsTypeClass: TypeClass[Double] = new TypeClass[Double] {
override def op(x: Double): Double = x
}
}
object TraitBounds {
trait Types1 {
type Member1
val cls1: TypeClass[Member1]
}
object Types1 {
private class Types1Impl[A](implicit ev: TypeClass[A]) extends Types1 {
override type Member1 = A
override val cls1 = ev
}
def apply[A: TypeClass]: Types1 = new Types1Impl[A]
}
trait Types2 {
type Member2
val cls2: TypeClass[Member2]
}
object Types2 {
private class Types2Impl[A](implicit ev: TypeClass[A]) extends Types2 {
override type Member2 = A
override val cls2 = ev
}
def apply[A: TypeClass]: Types2 = new Types2Impl[A]
}
trait AllTypes extends Types1 with Types2
object AllTypes {
def fromTypes(t1: Types1, t2: Types2): AllTypes = new AllTypes {
override type Member1 = t1.Member1
override val cls1 = t1.cls1
override type Member2 = t2.Member2
override val cls2 = t2.cls2
}
}
def mk(x: Int): AllTypes =
if (x == 1) {
AllTypes.fromTypes(Types1[Float], Types2[Double])
} else {
AllTypes.fromTypes(Types1[Double], Types2[Float])
}
def main(args: Array[String]): Unit = {
val in: AllTypes = mk(1)
println(in)
}
}
A couple of notes, always prefer implicit vals
and defs
with specific type signatures over implicit objects
, they tend up to mess the type system since an object is of type ThatObjectName.type
.
Also, hide your implementations behind factory constructors to shadow their types to the parent trait
.
edited Nov 23 at 14:14
answered Nov 22 at 15:27
Luis Miguel Mejía Suárez
1,467719
1,467719
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53433667%2fscala-type-mismatch-when-composing-traits%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown