Why does wrapping a method in another method stop type mismatch in Scala - using underscore in type parameter...





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







3















In the following block of code (with both scala 2.11 and 2.12) the method apply does not compile, while applyInlined does.



package blar

trait Bar[T]

class A
class B
class C

trait Exploder[T] {
// Removing explode and changing Foo so that
// flatMap takes no param means it will compile
def explode(product: C): Seq[T]
val bar: Bar[T]
}

case object Exploder1 extends Exploder[A] {
def explode(product: C): Seq[A] = ???
val bar: Bar[A] = ???
}

case object Exploder2 extends Exploder[B] {
def explode(product: C): Seq[B] = ???
val bar: Bar[B] = ???
}

object Thing {
def apply(): Unit = List(Exploder1, Exploder2).foreach {
case exploder: Exploder[_] =>
wrapped(exploder)
}

def applyInlined(): Unit = List(Exploder1, Exploder2).foreach {
case exploder: Exploder[_] =>
flatMap(exploder.explode)(exploder.bar)
}

def flatMap[U: Bar](explode: C => TraversableOnce[U]): Unit = ???

def wrapped[T](exploder: Exploder[T]): Unit =
flatMap(exploder.explode)(exploder.bar)
}


The error message is



[error] .../src/main/scala/blar/Bar.scala:34:42: type mismatch;
[error] found : blar.Bar[_1]
[error] required: blar.Bar[Object]
[error] Note: _1 <: Object, but trait Bar is invariant in type T.
[error] You may wish to define T as +T instead. (SLS 4.5)
[error] flatMap(exploder.explode)(exploder.bar)
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 4 s, completed 03-Jan-2019 13:43:45



  1. My main question is why? Is this a bug?


As you can see applyInlined only differs in that it has inlined the body of the wrapped method. This means that somehow the extra wrapping of some code in a method has "tricked" the compiler into working.




  1. The other question is can you think of a design/hack that would avoid this kind of thing without making Blar covariant? How can I make the inlined version compile? Can I do it with an asInstanceOf


  2. What is scala inferring the type to be in order to call wrapped without an explicit type param?











share|improve this question




















  • 2





    @LuisMiguelMejíaSuárez Because of [U: Bar], flatMap expects a second, implicit argument.

    – Andrey Tyukin
    Jan 3 at 14:34













  • @AndreyTyukin Ah yes, of course - my bad.

    – Luis Miguel Mejía Suárez
    Jan 3 at 14:53


















3















In the following block of code (with both scala 2.11 and 2.12) the method apply does not compile, while applyInlined does.



package blar

trait Bar[T]

class A
class B
class C

trait Exploder[T] {
// Removing explode and changing Foo so that
// flatMap takes no param means it will compile
def explode(product: C): Seq[T]
val bar: Bar[T]
}

case object Exploder1 extends Exploder[A] {
def explode(product: C): Seq[A] = ???
val bar: Bar[A] = ???
}

case object Exploder2 extends Exploder[B] {
def explode(product: C): Seq[B] = ???
val bar: Bar[B] = ???
}

object Thing {
def apply(): Unit = List(Exploder1, Exploder2).foreach {
case exploder: Exploder[_] =>
wrapped(exploder)
}

def applyInlined(): Unit = List(Exploder1, Exploder2).foreach {
case exploder: Exploder[_] =>
flatMap(exploder.explode)(exploder.bar)
}

def flatMap[U: Bar](explode: C => TraversableOnce[U]): Unit = ???

def wrapped[T](exploder: Exploder[T]): Unit =
flatMap(exploder.explode)(exploder.bar)
}


The error message is



[error] .../src/main/scala/blar/Bar.scala:34:42: type mismatch;
[error] found : blar.Bar[_1]
[error] required: blar.Bar[Object]
[error] Note: _1 <: Object, but trait Bar is invariant in type T.
[error] You may wish to define T as +T instead. (SLS 4.5)
[error] flatMap(exploder.explode)(exploder.bar)
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 4 s, completed 03-Jan-2019 13:43:45



  1. My main question is why? Is this a bug?


As you can see applyInlined only differs in that it has inlined the body of the wrapped method. This means that somehow the extra wrapping of some code in a method has "tricked" the compiler into working.




  1. The other question is can you think of a design/hack that would avoid this kind of thing without making Blar covariant? How can I make the inlined version compile? Can I do it with an asInstanceOf


  2. What is scala inferring the type to be in order to call wrapped without an explicit type param?











share|improve this question




















  • 2





    @LuisMiguelMejíaSuárez Because of [U: Bar], flatMap expects a second, implicit argument.

    – Andrey Tyukin
    Jan 3 at 14:34













  • @AndreyTyukin Ah yes, of course - my bad.

    – Luis Miguel Mejía Suárez
    Jan 3 at 14:53














3












3








3








In the following block of code (with both scala 2.11 and 2.12) the method apply does not compile, while applyInlined does.



package blar

trait Bar[T]

class A
class B
class C

trait Exploder[T] {
// Removing explode and changing Foo so that
// flatMap takes no param means it will compile
def explode(product: C): Seq[T]
val bar: Bar[T]
}

case object Exploder1 extends Exploder[A] {
def explode(product: C): Seq[A] = ???
val bar: Bar[A] = ???
}

case object Exploder2 extends Exploder[B] {
def explode(product: C): Seq[B] = ???
val bar: Bar[B] = ???
}

object Thing {
def apply(): Unit = List(Exploder1, Exploder2).foreach {
case exploder: Exploder[_] =>
wrapped(exploder)
}

def applyInlined(): Unit = List(Exploder1, Exploder2).foreach {
case exploder: Exploder[_] =>
flatMap(exploder.explode)(exploder.bar)
}

def flatMap[U: Bar](explode: C => TraversableOnce[U]): Unit = ???

def wrapped[T](exploder: Exploder[T]): Unit =
flatMap(exploder.explode)(exploder.bar)
}


The error message is



[error] .../src/main/scala/blar/Bar.scala:34:42: type mismatch;
[error] found : blar.Bar[_1]
[error] required: blar.Bar[Object]
[error] Note: _1 <: Object, but trait Bar is invariant in type T.
[error] You may wish to define T as +T instead. (SLS 4.5)
[error] flatMap(exploder.explode)(exploder.bar)
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 4 s, completed 03-Jan-2019 13:43:45



  1. My main question is why? Is this a bug?


As you can see applyInlined only differs in that it has inlined the body of the wrapped method. This means that somehow the extra wrapping of some code in a method has "tricked" the compiler into working.




  1. The other question is can you think of a design/hack that would avoid this kind of thing without making Blar covariant? How can I make the inlined version compile? Can I do it with an asInstanceOf


  2. What is scala inferring the type to be in order to call wrapped without an explicit type param?











share|improve this question
















In the following block of code (with both scala 2.11 and 2.12) the method apply does not compile, while applyInlined does.



package blar

trait Bar[T]

class A
class B
class C

trait Exploder[T] {
// Removing explode and changing Foo so that
// flatMap takes no param means it will compile
def explode(product: C): Seq[T]
val bar: Bar[T]
}

case object Exploder1 extends Exploder[A] {
def explode(product: C): Seq[A] = ???
val bar: Bar[A] = ???
}

case object Exploder2 extends Exploder[B] {
def explode(product: C): Seq[B] = ???
val bar: Bar[B] = ???
}

object Thing {
def apply(): Unit = List(Exploder1, Exploder2).foreach {
case exploder: Exploder[_] =>
wrapped(exploder)
}

def applyInlined(): Unit = List(Exploder1, Exploder2).foreach {
case exploder: Exploder[_] =>
flatMap(exploder.explode)(exploder.bar)
}

def flatMap[U: Bar](explode: C => TraversableOnce[U]): Unit = ???

def wrapped[T](exploder: Exploder[T]): Unit =
flatMap(exploder.explode)(exploder.bar)
}


The error message is



[error] .../src/main/scala/blar/Bar.scala:34:42: type mismatch;
[error] found : blar.Bar[_1]
[error] required: blar.Bar[Object]
[error] Note: _1 <: Object, but trait Bar is invariant in type T.
[error] You may wish to define T as +T instead. (SLS 4.5)
[error] flatMap(exploder.explode)(exploder.bar)
[error] ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed
[error] Total time: 4 s, completed 03-Jan-2019 13:43:45



  1. My main question is why? Is this a bug?


As you can see applyInlined only differs in that it has inlined the body of the wrapped method. This means that somehow the extra wrapping of some code in a method has "tricked" the compiler into working.




  1. The other question is can you think of a design/hack that would avoid this kind of thing without making Blar covariant? How can I make the inlined version compile? Can I do it with an asInstanceOf


  2. What is scala inferring the type to be in order to call wrapped without an explicit type param?








scala types covariance scalac scala-compiler






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 4 at 12:41







samthebest

















asked Jan 3 at 13:56









samthebestsamthebest

19.9k1475113




19.9k1475113








  • 2





    @LuisMiguelMejíaSuárez Because of [U: Bar], flatMap expects a second, implicit argument.

    – Andrey Tyukin
    Jan 3 at 14:34













  • @AndreyTyukin Ah yes, of course - my bad.

    – Luis Miguel Mejía Suárez
    Jan 3 at 14:53














  • 2





    @LuisMiguelMejíaSuárez Because of [U: Bar], flatMap expects a second, implicit argument.

    – Andrey Tyukin
    Jan 3 at 14:34













  • @AndreyTyukin Ah yes, of course - my bad.

    – Luis Miguel Mejía Suárez
    Jan 3 at 14:53








2




2





@LuisMiguelMejíaSuárez Because of [U: Bar], flatMap expects a second, implicit argument.

– Andrey Tyukin
Jan 3 at 14:34







@LuisMiguelMejíaSuárez Because of [U: Bar], flatMap expects a second, implicit argument.

– Andrey Tyukin
Jan 3 at 14:34















@AndreyTyukin Ah yes, of course - my bad.

– Luis Miguel Mejía Suárez
Jan 3 at 14:53





@AndreyTyukin Ah yes, of course - my bad.

– Luis Miguel Mejía Suárez
Jan 3 at 14:53












1 Answer
1






active

oldest

votes


















3
















  1. I don't know. Experimental evidence shows that it has something to do with the presence / absence of the explicit [Exploder[_]] type annotation on List. Without List[Exploder[_]], the inferred type of the list becomes



    List[Product with Serializable with Exploder[_ >: B with A <: Object]]


    and for whatever reason, it somehow messes up the subsequent pattern matching. The B with A lower bound looks a little suspicious to me, but I can't explain why it would interfere with the pattern matching.




  2. No, fortunately, no asInstanecOfs are required. Both of the following variants work fine:



    def applyInlined: Unit = List[Exploder[_]](Exploder1, Exploder2).foreach {
    case exploder: Exploder[t] => {
    flatMap(exploder.explode)(exploder.bar)
    }
    }


    same with a separately declared implicit variable (note that now you have some type t to refer to):



    def applyInlined2: Unit = List[Exploder[_]](Exploder1, Exploder2).foreach {
    case exploder: Exploder[t] => {
    implicit val bar: Bar[t] = exploder.bar
    flatMap(exploder.explode)
    }
    }


    See Type parameter inference in patterns for more about the [t]-part.



  3. I assume it's some synthetic dummy type _1.







share|improve this answer


























  • Thanks Andrey, especially for answer 2, now I can inline that useless method. Would be interesting to understand "for whatever reason, it somehow messes up the subsequent pattern matching".

    – samthebest
    Jan 4 at 16:40












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%2f54023745%2fwhy-does-wrapping-a-method-in-another-method-stop-type-mismatch-in-scala-using%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









3
















  1. I don't know. Experimental evidence shows that it has something to do with the presence / absence of the explicit [Exploder[_]] type annotation on List. Without List[Exploder[_]], the inferred type of the list becomes



    List[Product with Serializable with Exploder[_ >: B with A <: Object]]


    and for whatever reason, it somehow messes up the subsequent pattern matching. The B with A lower bound looks a little suspicious to me, but I can't explain why it would interfere with the pattern matching.




  2. No, fortunately, no asInstanecOfs are required. Both of the following variants work fine:



    def applyInlined: Unit = List[Exploder[_]](Exploder1, Exploder2).foreach {
    case exploder: Exploder[t] => {
    flatMap(exploder.explode)(exploder.bar)
    }
    }


    same with a separately declared implicit variable (note that now you have some type t to refer to):



    def applyInlined2: Unit = List[Exploder[_]](Exploder1, Exploder2).foreach {
    case exploder: Exploder[t] => {
    implicit val bar: Bar[t] = exploder.bar
    flatMap(exploder.explode)
    }
    }


    See Type parameter inference in patterns for more about the [t]-part.



  3. I assume it's some synthetic dummy type _1.







share|improve this answer


























  • Thanks Andrey, especially for answer 2, now I can inline that useless method. Would be interesting to understand "for whatever reason, it somehow messes up the subsequent pattern matching".

    – samthebest
    Jan 4 at 16:40
















3
















  1. I don't know. Experimental evidence shows that it has something to do with the presence / absence of the explicit [Exploder[_]] type annotation on List. Without List[Exploder[_]], the inferred type of the list becomes



    List[Product with Serializable with Exploder[_ >: B with A <: Object]]


    and for whatever reason, it somehow messes up the subsequent pattern matching. The B with A lower bound looks a little suspicious to me, but I can't explain why it would interfere with the pattern matching.




  2. No, fortunately, no asInstanecOfs are required. Both of the following variants work fine:



    def applyInlined: Unit = List[Exploder[_]](Exploder1, Exploder2).foreach {
    case exploder: Exploder[t] => {
    flatMap(exploder.explode)(exploder.bar)
    }
    }


    same with a separately declared implicit variable (note that now you have some type t to refer to):



    def applyInlined2: Unit = List[Exploder[_]](Exploder1, Exploder2).foreach {
    case exploder: Exploder[t] => {
    implicit val bar: Bar[t] = exploder.bar
    flatMap(exploder.explode)
    }
    }


    See Type parameter inference in patterns for more about the [t]-part.



  3. I assume it's some synthetic dummy type _1.







share|improve this answer


























  • Thanks Andrey, especially for answer 2, now I can inline that useless method. Would be interesting to understand "for whatever reason, it somehow messes up the subsequent pattern matching".

    – samthebest
    Jan 4 at 16:40














3












3








3









  1. I don't know. Experimental evidence shows that it has something to do with the presence / absence of the explicit [Exploder[_]] type annotation on List. Without List[Exploder[_]], the inferred type of the list becomes



    List[Product with Serializable with Exploder[_ >: B with A <: Object]]


    and for whatever reason, it somehow messes up the subsequent pattern matching. The B with A lower bound looks a little suspicious to me, but I can't explain why it would interfere with the pattern matching.




  2. No, fortunately, no asInstanecOfs are required. Both of the following variants work fine:



    def applyInlined: Unit = List[Exploder[_]](Exploder1, Exploder2).foreach {
    case exploder: Exploder[t] => {
    flatMap(exploder.explode)(exploder.bar)
    }
    }


    same with a separately declared implicit variable (note that now you have some type t to refer to):



    def applyInlined2: Unit = List[Exploder[_]](Exploder1, Exploder2).foreach {
    case exploder: Exploder[t] => {
    implicit val bar: Bar[t] = exploder.bar
    flatMap(exploder.explode)
    }
    }


    See Type parameter inference in patterns for more about the [t]-part.



  3. I assume it's some synthetic dummy type _1.







share|improve this answer

















  1. I don't know. Experimental evidence shows that it has something to do with the presence / absence of the explicit [Exploder[_]] type annotation on List. Without List[Exploder[_]], the inferred type of the list becomes



    List[Product with Serializable with Exploder[_ >: B with A <: Object]]


    and for whatever reason, it somehow messes up the subsequent pattern matching. The B with A lower bound looks a little suspicious to me, but I can't explain why it would interfere with the pattern matching.




  2. No, fortunately, no asInstanecOfs are required. Both of the following variants work fine:



    def applyInlined: Unit = List[Exploder[_]](Exploder1, Exploder2).foreach {
    case exploder: Exploder[t] => {
    flatMap(exploder.explode)(exploder.bar)
    }
    }


    same with a separately declared implicit variable (note that now you have some type t to refer to):



    def applyInlined2: Unit = List[Exploder[_]](Exploder1, Exploder2).foreach {
    case exploder: Exploder[t] => {
    implicit val bar: Bar[t] = exploder.bar
    flatMap(exploder.explode)
    }
    }


    See Type parameter inference in patterns for more about the [t]-part.



  3. I assume it's some synthetic dummy type _1.








share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 3 at 16:51

























answered Jan 3 at 14:55









Andrey TyukinAndrey Tyukin

30.7k42351




30.7k42351













  • Thanks Andrey, especially for answer 2, now I can inline that useless method. Would be interesting to understand "for whatever reason, it somehow messes up the subsequent pattern matching".

    – samthebest
    Jan 4 at 16:40



















  • Thanks Andrey, especially for answer 2, now I can inline that useless method. Would be interesting to understand "for whatever reason, it somehow messes up the subsequent pattern matching".

    – samthebest
    Jan 4 at 16:40

















Thanks Andrey, especially for answer 2, now I can inline that useless method. Would be interesting to understand "for whatever reason, it somehow messes up the subsequent pattern matching".

– samthebest
Jan 4 at 16:40





Thanks Andrey, especially for answer 2, now I can inline that useless method. Would be interesting to understand "for whatever reason, it somehow messes up the subsequent pattern matching".

– samthebest
Jan 4 at 16:40




















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%2f54023745%2fwhy-does-wrapping-a-method-in-another-method-stop-type-mismatch-in-scala-using%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

Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

ts Property 'filter' does not exist on type '{}'

mat-slide-toggle shouldn't change it's state when I click cancel in confirmation window