Note that there are some explanatory texts on larger screens.

plurals
  1. POScala type inference fails to note that these types are identical, whatever they are
    primarykey
    data
    text
    <p>I have a design pattern here where there is an object generator (MorselGenerator and its children), any instance of which always generates the same exact type of object (Morsels and its children), but the type checker will not let me perform any operations on two or more of these generated objects, believing they might be different. </p> <p>How do I get this past the type checker?</p> <pre><code>trait Morsel { type M &lt;: Morsel def calories : Float def + (v : M) : M } trait MorselGenerator { type Mg &lt;: Morsel def generateMorsel : Mg } class HotDog(c : Float, l : Float, w : Float) extends Morsel { type M = HotDog val calories : Float = c val length : Float = l val width : Float = w def + (v : HotDog) : HotDog = new HotDog(v.calories + calories, v.length + length, v.width + width) } class HotDogGenerator extends MorselGenerator { type Mg = HotDog def generateMorsel : HotDog = new HotDog(500.0f, 3.14159f, 445.1f) } object Factory { def main ( args : Array[String] ) { val hdGen = new HotDogGenerator() println(eatTwo(hdGen)) } def eatTwo ( mGen : MorselGenerator ) { val v0 : mGen.Mg = mGen.generateMorsel val v1 : mGen.Mg = mGen.generateMorsel v0 + v1 /// ERROR HERE } } </code></pre> <p>Compiler generates the following compile error</p> <pre><code>Generator.scala:43: error: type mismatch; found : v1.type (with underlying type mGen.Mg) required: v0.M v0 + v1 /// ERROR HERE ^ one error found </code></pre> <p><br></p> <h1>Update</h1> <p>Here is C++ code that is more or less equivalent to what I'm trying to do. Note that the eatTwo function is fully polymorphic and makes no reference to specific derived types of Morsel or MorselGenerator.</p> <pre><code>#include &lt;stdlib.h&gt; #include &lt;stdio.h&gt; template &lt;class M&gt; class Morsel { public: Morsel(float c) : calories(c) {} float calories; virtual M operator + (const M&amp; rhs) const = 0; }; template &lt;class M&gt; class MorselGenerator { public: virtual M * generateMorsel() const = 0; }; class HotDog : public Morsel&lt;HotDog&gt; { public: HotDog(float c, float l, float w) : Morsel&lt;HotDog&gt;(c), length(l), width(w) {} float length, width; HotDog operator + (const HotDog&amp; rhs) const { return HotDog(calories+rhs.calories, length+rhs.length, width+rhs.width); } }; class HotDogGenerator : public MorselGenerator&lt;HotDog&gt; { HotDog * generateMorsel() const { return new HotDog(500.0f, 3.14159f, 445.1f); } }; /////////////////////////////////////////////// template &lt;class MorselType&gt; float eatTwo ( const MorselGenerator&lt;MorselType&gt;&amp; mGen) { MorselType * m0 = mGen.generateMorsel(); MorselType * m1 = mGen.generateMorsel(); float sum = ((*m0) + (*m1)).calories; delete m0; delete m1; return sum; } int main() { MorselGenerator&lt;HotDog&gt; * morselStream = new HotDogGenerator(); printf("Calories Ingested: %.2f\n", eatTwo(*morselStream)); delete morselStream; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload