Scala type mismatch when composing traits












0















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?










share|improve this question





























    0















    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?










    share|improve this question



























      0












      0








      0








      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?










      share|improve this question
















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 22 '18 at 15:16







      fusion

















      asked Nov 22 '18 at 15:01









      fusionfusion

      883512




      883512
























          1 Answer
          1






          active

          oldest

          votes


















          2














          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.






          share|improve this answer

























            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
            });


            }
            });














            draft saved

            draft discarded


















            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









            2














            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.






            share|improve this answer






























              2














              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.






              share|improve this answer




























                2












                2








                2







                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.






                share|improve this answer















                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.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                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






























                    draft saved

                    draft discarded




















































                    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.




                    draft saved


                    draft discarded














                    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





















































                    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







                    Popular posts from this blog

                    404 Error Contact Form 7 ajax form submitting

                    How to know if a Active Directory user can login interactively

                    TypeError: fit_transform() missing 1 required positional argument: 'X'