Why does this snippet with matching patterns and higher type types no longer compile in Scala 2.12?

I am working on a piece of code that looks like this ( Scastie for your convenience ):

import scala.language.higherKinds

sealed trait Wrapping
sealed trait PinkWrap extends Wrapping
sealed trait GreenWrap extends Wrapping

sealed trait Foo[M[_], A] {}
case class MintFoo[M[_], A](a : A) extends Foo[M,A]
case class LiquoriceFoo[M[_], A](a : A) extends Foo[M,A]
sealed trait WrappedFoo[M[_], _, A]
case class FooInPinkWrap[M[_], A](m: Foo[M, A]) extends WrappedFoo[M, PinkWrap, A]
case class FooInGreenWrap[M[_], A](m: Foo[M, A]) extends WrappedFoo[M, GreenWrap, A]

object Utils {
   def analyzeFoo[M[_], S <: Wrapping, A](w: WrappedFoo[M, S, A]): String = {
    w match {
      case FooInPinkWrap(f: Foo[M,A]) => tasteFoo[M,A](f)+" in Pink wrapping"      
      case FooInGreenWrap(f: Foo[M,A]) => tasteFoo[M,A](f)+" in Green wrapping"
    }
  }

  def tasteFoo[M[_], A](f: Foo[M,A]) : String = 
   f match {
     case MintFoo (a) => "Mint"
     case LiquoriceFoo (a) => "Liquorice"
   }
}   

It compiled fine with Scala 2.11.7.

Since the project was attached to Scala 2.12.4 (but in fact the problem is already reproduced using Scala 2.11.11), it cannot be compiled with the following message from scalacfor the line case FooInPinkWrap(f: Foo[M,A]) => tasteFoo[M,A]:

M takes no type parameters, expected: one

This reproduces directly in Scastie by selecting Scala Version 2.12.4 in the Build Settings section.

This puzzles me, as it is Mreally 1-ar.

In fact, I am facing the same problem with the following, simpler MWE ( Scastie ):

import scala.language.higherKinds

sealed trait GiftWrap
sealed trait PinkWrap extends GiftWrap
sealed trait GreenWrap extends GiftWrap

sealed trait Foo[M[_], A] {}
sealed trait WrappedFoo[M[_], S, A]
case class FooInPinkWrap[M[_], A](m: Foo[M, A]) extends WrappedFoo[M, PinkWrap, A]
case class FooInGreenWrap[M[_], A](m: Foo[M, A]) extends WrappedFoo[M, GreenWrap, A]

object Utils {
   def tellColor[M[_], S <: GiftWrap, A](w: WrappedFoo[M, S, A]): String = {
    w match {
      case FooInPinkWrap(f: Foo[M,A]) => "Pink"
      case FooInGreenWrap(f: Foo[M,A]) => "Green"
    }
  }
}

M ({type T[X] = M[X]})#T

pattern type is incompatible with expected type;
 found   : Playground.this.Foo[[X],A]
 required: Playground.this.Foo[Any,Any]
Note: [X] <: Any, but trait Foo is invariant in type M.
You may wish to define M as +M instead. (SLS 4.5)
Note: A <: Any, but trait Foo is invariant in type A.
You may wish to define A as +A instead. (SLS 4.5)

M does not take type parameters

found : Playground.this.Foo[[X],A].

?

2.11.11 ( ), .

,

  • ?

.

+4
1

Edit-

:


,

"" , . Foo . :

sealed trait Foo[M[_], P]
case class Bar[M[_]]() extends Foo[M, Int]

def f[M[_], S](x: Foo[M, S]): Int = x match {
  case Bar() => g[M]
}

def g[M[_]] = 0

2.12.4 :

error: M takes no type parameters, expected: one
  case Bar() => g[M]
                  ^
one error found

- P of Foo, Int Bar, S f.

, . , , , , 2.11, 2.12.

, , .

1. :

sealed trait Foo[M[_], P]
case class Bar[M[_]]() extends Foo[M, Int]

def f[M[_], S](x: Foo[M, S]): Int = x match {
  case b: Bar[M] => g[M]
}

def g[M[_]] = 0

2. (, Scala match - case!), , [Odersky et al. " Scala", , . 275]:

().

, , m:

sealed trait Foo[M[_], P]
case class Bar[M[_]]() extends Foo[M, Int]

def f[M[_], S](x: Foo[M, S]): Int = x match {
  case b: Bar[M] => g[M]
}

def g[M[_]] = 0

}

3. RHS case Bar:

sealed trait Foo[M[_], P]
case class Bar[M[_]]() extends Foo[M, Int] {
  def g: Int = 0
}

def f[M[_], S](x: Foo[M, S]): Int = x match {
  case b @ Bar() => b.g
}

4. ( , )

, P Int , :

sealed trait Foo[M[_], P]
case class Bar[M[_]]() extends Foo[M, Int]

def f[M[_]](x: Foo[M, Int]): Int = x match {
  case Bar() => g[M]
}

def g[M[_]] = 0

, :

1. :

import scala.language.higherKinds

sealed trait Wrapping
sealed trait PinkWrap extends Wrapping
sealed trait GreenWrap extends Wrapping

sealed trait Foo[M[_], A] {}
case class MintFoo[M[_], A](a : A) extends Foo[M, A]
case class LiquoriceFoo[M[_], A](a : A) extends Foo[M, A]
sealed trait WrappedFoo[M[_], _, A]
case class FooInPinkWrap[M[_], A](m: Foo[M, A]) extends WrappedFoo[M, PinkWrap, A]
case class FooInGreenWrap[M[_], A](m: Foo[M, A]) extends WrappedFoo[M, GreenWrap, A]

object Utils {
  def analyzeFoo[M[_], S <: Wrapping, A](w: WrappedFoo[M, S, A]): String = {
    w match {
      case f: FooInPinkWrap[M, A] => tasteFoo[M, A](f.m) + " in Pink wrapping"      
      case f: FooInGreenWrap[M, A] => tasteFoo[M, A](f.m) + " in Green wrapping"
    }
  }

  def tasteFoo[M[_], A](f: Foo[M,A]) : String = {
    f match {
      case MintFoo(a) => "Mint"
      case LiquoriceFoo(a) => "Liquorice"
    }
  }
}

2. :

sealed trait Wrapping
sealed trait PinkWrap extends Wrapping
sealed trait GreenWrap extends Wrapping

sealed trait Foo[M[_], A] {}
case class MintFoo[M[_], A](a : A) extends Foo[M, A]
case class LiquoriceFoo[M[_], A](a : A) extends Foo[M, A]
sealed trait WrappedFoo[M[_], _, A]
case class FooInPinkWrap[M[_], A](m: Foo[M, A]) extends WrappedFoo[M, PinkWrap, A]
case class FooInGreenWrap[M[_], A](m: Foo[M, A]) extends WrappedFoo[M, GreenWrap, A]

object Utils {
  def analyzeFoo[M[_], S <: Wrapping, A](w: WrappedFoo[M, S, A]): String = {
    w match {
      case f: FooInPinkWrap[m, a] => tasteFoo[m, a](f.m) + " in Pink wrapping"      
      case f: FooInGreenWrap[m, a] => tasteFoo[m, a](f.m) + " in Green wrapping"
    }
  }

  def tasteFoo[M[_], A](f: Foo[M,A]) : String = {
    f match {
      case MintFoo(a) => "Mint"
      case LiquoriceFoo(a) => "Liquorice"
    }
  }
}

3: tasteBlah WrappedFoo:

sealed trait Wrapping
sealed trait PinkWrap extends Wrapping
sealed trait GreenWrap extends Wrapping

sealed trait Foo[M[_], A] {}
case class MintFoo[M[_], A](a : A) extends Foo[M, A]
case class LiquoriceFoo[M[_], A](a : A) extends Foo[M, A]
sealed trait WrappedFoo[M[_], _, A] {
  def m: Foo[M, A]
  def tasteFoo: String = {
    m match {
      case MintFoo(a) => "Mint"
      case LiquoriceFoo(a) => "Liquorice"
    }
  }
}
case class FooInPinkWrap[M[_], A](m: Foo[M, A]) extends WrappedFoo[M, PinkWrap, A]
case class FooInGreenWrap[M[_], A](m: Foo[M, A]) extends WrappedFoo[M, GreenWrap, A]

object Utils {
  def analyzeFoo[M[_], S <: Wrapping, A](w: WrappedFoo[M, S, A]): String = {
    w match {
      case f: FooInPinkWrap[M, A] => f.tasteFoo + " in Pink wrapping"      
      case f: FooInGreenWrap[M, A] => f.tasteFoo + " in Green wrapping"
    }
  }
}

4 ( , ).


( ): , , . - , , .

+2

Source: https://habr.com/ru/post/1695086/


All Articles