Scala type mismatch when composing traits
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 |
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 |
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 '18 at 15:16
fusion
asked Nov 22 '18 at 15:01
fusionfusion
883512
883512
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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 |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
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 |
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 |
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 '18 at 14:14
answered Nov 22 '18 at 15:27
Luis Miguel Mejía SuárezLuis Miguel Mejía Suárez
2,1171721
2,1171721
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.
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