Can Be Matched As

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Can Be Matched As

Seyed H. HAERI (Hossein)
Dear all,

How can

trait t {
  type T
}

enforce that T has an extractor which takes say an Int? I tried

trait t {
  type T <: {def isEmpty: Boolean; def get}
  val T: {def unapply(i: Int): T}

  def test(a: Any): Unit = a match {case T(i) => println("")}
}

object o extends t {
  case class C(i: Int)

  type T = C//(*)
  val T = C//(**)
}

but, get the following two errors at (*) and (**), respectively:

(*) overriding type T in trait t with bounds <: AnyRef{def isEmpty:
Boolean; def get: Unit}; type T has incompatible type

(**) overriding value T in trait t of type AnyRef{def unapply(i: Int):
o.T}; value T has incompatible type

Why is that?

TIA,
--Hossein

--------------------------------------------------------------------------------------------------------------

Seyed H. HAERI (Hossein), Dr.

Post-Doctoral Research Fellow
Department of Computing Science and Engineering
Catholic University of Louvain
Louvain-la-Neuve, Belgium

ACCU - Professionalism in programming - http://www.accu.org/
--------------------------------------------------------------------------------------------------------------

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Can Be Matched As

Naftoli Gugenheim

First of all, a few of your types are wrong.

As you can see from the error message, def get with no type is assumed to return Unit.

type C does not have isEmpty and get methods
unapply (an extractor) goes from an existing value and returns its parameters in an Option (remember, we’re deconstructing), which is the opposite of you have it.

However, after fixing it to this:

trait t {
  type T
  val T: {def unapply(t: T): Option[Int]}

  def test(a: Any): Unit = a match {case T(i) => println("")}
}

object o extends t {
  case class C(i: Int)

  type T = C
  val T = C//(**)
}

The compiler complains,

/tmp/test.scala:5: warning: abstract type pattern t.this.T is unchecked since it is eliminated by erasure
  def test(a: Any): Unit = a match {case T(i) => println("")}
                                          ^
/tmp/test.scala:3: error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement
  val T: {def unapply(t: T): Option[Int]}
                      ^
one warning found
one error found

(The first warning sounds like a compiler bug.)

However, similar to your other question, we can achieve the bigger-picture goal by passing functions around. This works:

trait t {
  type T
  def extractT: T => Option[Int]

  object T {
    def unapply(t: T) = extractT(t)
  }

  def test(a: Any): Unit = a match {case T(i) => println(i)}
}

object o extends t {
  case class C(i: Int)

  type T = C
  def extractT = C.unapply
}

On Tue, Apr 25, 2017 at 8:07 PM Seyed H. HAERI (Hossein) <[hidden email]> wrote:
Dear all,

How can

trait t {
  type T
}

enforce that T has an extractor which takes say an Int? I tried

trait t {
  type T <: {def isEmpty: Boolean; def get}
  val T: {def unapply(i: Int): T}

  def test(a: Any): Unit = a match {case T(i) => println("")}
}

object o extends t {
  case class C(i: Int)

  type T = C//(*)
  val T = C//(**)
}

but, get the following two errors at (*) and (**), respectively:

(*) overriding type T in trait t with bounds <: AnyRef{def isEmpty:
Boolean; def get: Unit}; type T has incompatible type

(**) overriding value T in trait t of type AnyRef{def unapply(i: Int):
o.T}; value T has incompatible type

Why is that?

TIA,
--Hossein

--------------------------------------------------------------------------------------------------------------

Seyed H. HAERI (Hossein), Dr.

Post-Doctoral Research Fellow
Department of Computing Science and Engineering
Catholic University of Louvain
Louvain-la-Neuve, Belgium

ACCU - Professionalism in programming - http://www.accu.org/
--------------------------------------------------------------------------------------------------------------

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Can Be Matched As

Seyed H. HAERI (Hossein)
Thank you Naftoli. That was very helpful. :)

On 26 April 2017 at 02:54, Naftoli Gugenheim <[hidden email]> wrote:

> First of all, a few of your types are wrong.
>
> As you can see from the error message, def get with no type is assumed to
> return Unit.
>
> type C does not have isEmpty and get methods
> unapply (an extractor) goes from an existing value and returns its
> parameters in an Option (remember, we’re deconstructing), which is the
> opposite of you have it.
>
> However, after fixing it to this:
>
> trait t {
>   type T
>   val T: {def unapply(t: T): Option[Int]}
>
>   def test(a: Any): Unit = a match {case T(i) => println("")}
> }
>
> object o extends t {
>   case class C(i: Int)
>
>   type T = C
>   val T = C//(**)
> }
>
> The compiler complains,
>
> /tmp/test.scala:5: warning: abstract type pattern t.this.T is unchecked
> since it is eliminated by erasure
>   def test(a: Any): Unit = a match {case T(i) => println("")}
>                                           ^
> /tmp/test.scala:3: error: Parameter type in structural refinement may not
> refer to an abstract type defined outside that refinement
>   val T: {def unapply(t: T): Option[Int]}
>                       ^
> one warning found
> one error found
>
> (The first warning sounds like a compiler bug.)
>
> However, similar to your other question, we can achieve the bigger-picture
> goal by passing functions around. This works:
>
> trait t {
>   type T
>   def extractT: T => Option[Int]
>
>   object T {
>     def unapply(t: T) = extractT(t)
>   }
>
>   def test(a: Any): Unit = a match {case T(i) => println(i)}
> }
>
> object o extends t {
>   case class C(i: Int)
>
>   type T = C
>   def extractT = C.unapply
> }
>
>
> On Tue, Apr 25, 2017 at 8:07 PM Seyed H. HAERI (Hossein)
> <[hidden email]> wrote:
>>
>> Dear all,
>>
>> How can
>>
>> trait t {
>>   type T
>> }
>>
>> enforce that T has an extractor which takes say an Int? I tried
>>
>> trait t {
>>   type T <: {def isEmpty: Boolean; def get}
>>   val T: {def unapply(i: Int): T}
>>
>>   def test(a: Any): Unit = a match {case T(i) => println("")}
>> }
>>
>> object o extends t {
>>   case class C(i: Int)
>>
>>   type T = C//(*)
>>   val T = C//(**)
>> }
>>
>> but, get the following two errors at (*) and (**), respectively:
>>
>> (*) overriding type T in trait t with bounds <: AnyRef{def isEmpty:
>> Boolean; def get: Unit}; type T has incompatible type
>>
>> (**) overriding value T in trait t of type AnyRef{def unapply(i: Int):
>> o.T}; value T has incompatible type
>>
>> Why is that?
>>
>> TIA,
>> --Hossein
>>
>>
>> --------------------------------------------------------------------------------------------------------------
>>
>> Seyed H. HAERI (Hossein), Dr.
>>
>> Post-Doctoral Research Fellow
>> Department of Computing Science and Engineering
>> Catholic University of Louvain
>> Louvain-la-Neuve, Belgium
>>
>> ACCU - Professionalism in programming - http://www.accu.org/
>>
>> --------------------------------------------------------------------------------------------------------------
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "scala-user" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [hidden email].
>> For more options, visit https://groups.google.com/d/optout.



--
--------------------------------------------------------------------------------------------------------------

Seyed H. HAERI (Hossein), Dr.

Post-Doctoral Research Fellow
Department of Computing Science and Engineering
Catholic University of Louvain
Louvain-la-Neuve, Belgium

ACCU - Professionalism in programming - http://www.accu.org/
--------------------------------------------------------------------------------------------------------------

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Can Be Matched As

Seyed H. HAERI (Hossein)
Hi Naftoli,

One more thing: When I try

object T {
  def unapply = extractT(_)
}

I get

an unapply result must have a member `def isEmpty: Boolean

under "T(i)" in

def test(a: Any): Unit = a match {case T(i) => println(i)}

Is that a bug?

TIA,
--Hossein

P.S. How do you get to embed Scala so beautifully in your postings?


On 26 April 2017 at 13:58, Seyed H. HAERI (Hossein)
<[hidden email]> wrote:

> Thank you Naftoli. That was very helpful. :)
>
> On 26 April 2017 at 02:54, Naftoli Gugenheim <[hidden email]> wrote:
>> First of all, a few of your types are wrong.
>>
>> As you can see from the error message, def get with no type is assumed to
>> return Unit.
>>
>> type C does not have isEmpty and get methods
>> unapply (an extractor) goes from an existing value and returns its
>> parameters in an Option (remember, we’re deconstructing), which is the
>> opposite of you have it.
>>
>> However, after fixing it to this:
>>
>> trait t {
>>   type T
>>   val T: {def unapply(t: T): Option[Int]}
>>
>>   def test(a: Any): Unit = a match {case T(i) => println("")}
>> }
>>
>> object o extends t {
>>   case class C(i: Int)
>>
>>   type T = C
>>   val T = C//(**)
>> }
>>
>> The compiler complains,
>>
>> /tmp/test.scala:5: warning: abstract type pattern t.this.T is unchecked
>> since it is eliminated by erasure
>>   def test(a: Any): Unit = a match {case T(i) => println("")}
>>                                           ^
>> /tmp/test.scala:3: error: Parameter type in structural refinement may not
>> refer to an abstract type defined outside that refinement
>>   val T: {def unapply(t: T): Option[Int]}
>>                       ^
>> one warning found
>> one error found
>>
>> (The first warning sounds like a compiler bug.)
>>
>> However, similar to your other question, we can achieve the bigger-picture
>> goal by passing functions around. This works:
>>
>> trait t {
>>   type T
>>   def extractT: T => Option[Int]
>>
>>   object T {
>>     def unapply(t: T) = extractT(t)
>>   }
>>
>>   def test(a: Any): Unit = a match {case T(i) => println(i)}
>> }
>>
>> object o extends t {
>>   case class C(i: Int)
>>
>>   type T = C
>>   def extractT = C.unapply
>> }
>>
>>
>> On Tue, Apr 25, 2017 at 8:07 PM Seyed H. HAERI (Hossein)
>> <[hidden email]> wrote:
>>>
>>> Dear all,
>>>
>>> How can
>>>
>>> trait t {
>>>   type T
>>> }
>>>
>>> enforce that T has an extractor which takes say an Int? I tried
>>>
>>> trait t {
>>>   type T <: {def isEmpty: Boolean; def get}
>>>   val T: {def unapply(i: Int): T}
>>>
>>>   def test(a: Any): Unit = a match {case T(i) => println("")}
>>> }
>>>
>>> object o extends t {
>>>   case class C(i: Int)
>>>
>>>   type T = C//(*)
>>>   val T = C//(**)
>>> }
>>>
>>> but, get the following two errors at (*) and (**), respectively:
>>>
>>> (*) overriding type T in trait t with bounds <: AnyRef{def isEmpty:
>>> Boolean; def get: Unit}; type T has incompatible type
>>>
>>> (**) overriding value T in trait t of type AnyRef{def unapply(i: Int):
>>> o.T}; value T has incompatible type
>>>
>>> Why is that?
>>>
>>> TIA,
>>> --Hossein
>>>
>>>
>>> --------------------------------------------------------------------------------------------------------------
>>>
>>> Seyed H. HAERI (Hossein), Dr.
>>>
>>> Post-Doctoral Research Fellow
>>> Department of Computing Science and Engineering
>>> Catholic University of Louvain
>>> Louvain-la-Neuve, Belgium
>>>
>>> ACCU - Professionalism in programming - http://www.accu.org/
>>>
>>> --------------------------------------------------------------------------------------------------------------
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "scala-user" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an
>>> email to [hidden email].
>>> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> --------------------------------------------------------------------------------------------------------------
>
> Seyed H. HAERI (Hossein), Dr.
>
> Post-Doctoral Research Fellow
> Department of Computing Science and Engineering
> Catholic University of Louvain
> Louvain-la-Neuve, Belgium
>
> ACCU - Professionalism in programming - http://www.accu.org/
> --------------------------------------------------------------------------------------------------------------



--
--------------------------------------------------------------------------------------------------------------

Seyed H. HAERI (Hossein), Dr.

Post-Doctoral Research Fellow
Department of Computing Science and Engineering
Catholic University of Louvain
Louvain-la-Neuve, Belgium

ACCU - Professionalism in programming - http://www.accu.org/
--------------------------------------------------------------------------------------------------------------

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Can Be Matched As

Naftoli Gugenheim


On Wed, Apr 26, 2017, 8:09 AM Seyed H. HAERI (Hossein) <[hidden email]> wrote:
Hi Naftoli,

One more thing: When I try

object T {
  def unapply = extractT(_)
}

I get

an unapply result must have a member `def isEmpty: Boolean

under "T(i)" in

def test(a: Any): Unit = a match {case T(i) => println(i)}

Is that a bug?

Unapply usually returns Option. (As the message indicates it's more flexible, however unless you have a performance reason, Option is the easiest way.)


TIA,
--Hossein

P.S. How do you get to embed Scala so beautifully in your postings?

Markdown Here browser extension. I write the blocks like this:

```scala
// code
```

And press ctrl-alt-m before sending.




On 26 April 2017 at 13:58, Seyed H. HAERI (Hossein)
<[hidden email]> wrote:
> Thank you Naftoli. That was very helpful. :)
>
> On 26 April 2017 at 02:54, Naftoli Gugenheim <[hidden email]> wrote:
>> First of all, a few of your types are wrong.
>>
>> As you can see from the error message, def get with no type is assumed to
>> return Unit.
>>
>> type C does not have isEmpty and get methods
>> unapply (an extractor) goes from an existing value and returns its
>> parameters in an Option (remember, we’re deconstructing), which is the
>> opposite of you have it.
>>
>> However, after fixing it to this:
>>
>> trait t {
>>   type T
>>   val T: {def unapply(t: T): Option[Int]}
>>
>>   def test(a: Any): Unit = a match {case T(i) => println("")}
>> }
>>
>> object o extends t {
>>   case class C(i: Int)
>>
>>   type T = C
>>   val T = C//(**)
>> }
>>
>> The compiler complains,
>>
>> /tmp/test.scala:5: warning: abstract type pattern t.this.T is unchecked
>> since it is eliminated by erasure
>>   def test(a: Any): Unit = a match {case T(i) => println("")}
>>                                           ^
>> /tmp/test.scala:3: error: Parameter type in structural refinement may not
>> refer to an abstract type defined outside that refinement
>>   val T: {def unapply(t: T): Option[Int]}
>>                       ^
>> one warning found
>> one error found
>>
>> (The first warning sounds like a compiler bug.)
>>
>> However, similar to your other question, we can achieve the bigger-picture
>> goal by passing functions around. This works:
>>
>> trait t {
>>   type T
>>   def extractT: T => Option[Int]
>>
>>   object T {
>>     def unapply(t: T) = extractT(t)
>>   }
>>
>>   def test(a: Any): Unit = a match {case T(i) => println(i)}
>> }
>>
>> object o extends t {
>>   case class C(i: Int)
>>
>>   type T = C
>>   def extractT = C.unapply
>> }
>>
>>
>> On Tue, Apr 25, 2017 at 8:07 PM Seyed H. HAERI (Hossein)
>> <[hidden email]> wrote:
>>>
>>> Dear all,
>>>
>>> How can
>>>
>>> trait t {
>>>   type T
>>> }
>>>
>>> enforce that T has an extractor which takes say an Int? I tried
>>>
>>> trait t {
>>>   type T <: {def isEmpty: Boolean; def get}
>>>   val T: {def unapply(i: Int): T}
>>>
>>>   def test(a: Any): Unit = a match {case T(i) => println("")}
>>> }
>>>
>>> object o extends t {
>>>   case class C(i: Int)
>>>
>>>   type T = C//(*)
>>>   val T = C//(**)
>>> }
>>>
>>> but, get the following two errors at (*) and (**), respectively:
>>>
>>> (*) overriding type T in trait t with bounds <: AnyRef{def isEmpty:
>>> Boolean; def get: Unit}; type T has incompatible type
>>>
>>> (**) overriding value T in trait t of type AnyRef{def unapply(i: Int):
>>> o.T}; value T has incompatible type
>>>
>>> Why is that?
>>>
>>> TIA,
>>> --Hossein
>>>
>>>
>>> --------------------------------------------------------------------------------------------------------------
>>>
>>> Seyed H. HAERI (Hossein), Dr.
>>>
>>> Post-Doctoral Research Fellow
>>> Department of Computing Science and Engineering
>>> Catholic University of Louvain
>>> Louvain-la-Neuve, Belgium
>>>
>>> ACCU - Professionalism in programming - http://www.accu.org/
>>>
>>> --------------------------------------------------------------------------------------------------------------
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups
>>> "scala-user" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an
>>> email to [hidden email].
>>> For more options, visit https://groups.google.com/d/optout.
>
>
>
> --
> --------------------------------------------------------------------------------------------------------------
>
> Seyed H. HAERI (Hossein), Dr.
>
> Post-Doctoral Research Fellow
> Department of Computing Science and Engineering
> Catholic University of Louvain
> Louvain-la-Neuve, Belgium
>
> ACCU - Professionalism in programming - http://www.accu.org/
> --------------------------------------------------------------------------------------------------------------



--
--------------------------------------------------------------------------------------------------------------

Seyed H. HAERI (Hossein), Dr.

Post-Doctoral Research Fellow
Department of Computing Science and Engineering
Catholic University of Louvain
Louvain-la-Neuve, Belgium

ACCU - Professionalism in programming - http://www.accu.org/
--------------------------------------------------------------------------------------------------------------

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Can Be Matched As

Seyed H. HAERI (Hossein)
Hi Naftoli,

>> object T {
>>   def unapply = extractT(_)
>> }
>>
>> I get
>>
>> an unapply result must have a member `def isEmpty: Boolean
>>
>> under "T(i)" in
>>
>> def test(a: Any): Unit = a match {case T(i) => println(i)}
>>
>> Is that a bug?
>
> Unapply usually returns Option.

But, so does also extractT. You wrote:

def extractT: T => Option[Int]

> (As the message indicates it's more flexible, however unless you have a performance reason, Option is the easiest way.)

Sorry, I'm not following. How is that related?

> Markdown Here browser extension.

Cool. It unfortunately is not available on the old version of my
browser which I insist on using. Thank you anyway. :)

Cheers,
--Hossein

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Can Be Matched As

Naftoli Gugenheim


On Wed, Apr 26, 2017, 1:30 PM Seyed H. HAERI (Hossein) <[hidden email]> wrote:
Hi Naftoli,

>> object T {
>>   def unapply = extractT(_)
>> }
>>
>> I get
>>
>> an unapply result must have a member `def isEmpty: Boolean
>>
>> under "T(i)" in
>>
>> def test(a: Any): Unit = a match {case T(i) => println(i)}
>>
>> Is that a bug?
>
> Unapply usually returns Option.

But, so does also extractT. You wrote:

def extractT: T => Option[Int]

I guess it's because you're returning a function rather than defining it like a regular method the way I showed above


> (As the message indicates it's more flexible, however unless you have a performance reason, Option is the easiest way.)

Sorry, I'm not following. How is that related?

It doesn't say unapply result must be Option, because technically it could instead be anything that has isEmpty and get. But for normal usage, we can pretend it said result must be Option.


> Markdown Here browser extension.

Cool. It unfortunately is not available on the old version of my
browser which I insist on using. Thank you anyway. :)

Cheers,
--Hossein

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Can Be Matched As

Seyed H. HAERI (Hossein)
Thank you Naftoli.

On 26 April 2017 at 20:06, Naftoli Gugenheim <[hidden email]> wrote:

>
>
> On Wed, Apr 26, 2017, 1:30 PM Seyed H. HAERI (Hossein)
> <[hidden email]> wrote:
>>
>> Hi Naftoli,
>>
>> >> object T {
>> >>   def unapply = extractT(_)
>> >> }
>> >>
>> >> I get
>> >>
>> >> an unapply result must have a member `def isEmpty: Boolean
>> >>
>> >> under "T(i)" in
>> >>
>> >> def test(a: Any): Unit = a match {case T(i) => println(i)}
>> >>
>> >> Is that a bug?
>> >
>> > Unapply usually returns Option.
>>
>> But, so does also extractT. You wrote:
>>
>> def extractT: T => Option[Int]
>
>
> I guess it's because you're returning a function rather than defining it
> like a regular method the way I showed above
>
>>
>> > (As the message indicates it's more flexible, however unless you have a
>> > performance reason, Option is the easiest way.)
>>
>> Sorry, I'm not following. How is that related?
>
>
> It doesn't say unapply result must be Option, because technically it could
> instead be anything that has isEmpty and get. But for normal usage, we can
> pretend it said result must be Option.
>
>>
>> > Markdown Here browser extension.
>>
>> Cool. It unfortunately is not available on the old version of my
>> browser which I insist on using. Thank you anyway. :)
>>
>> Cheers,
>> --Hossein
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "scala-user" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to [hidden email].
>> For more options, visit https://groups.google.com/d/optout.



--
--------------------------------------------------------------------------------------------------------------

Seyed H. HAERI (Hossein), Dr.

Post-Doctoral Research Fellow
Department of Computing Science and Engineering
Catholic University of Louvain
Louvain-la-Neuve, Belgium

ACCU - Professionalism in programming - http://www.accu.org/
--------------------------------------------------------------------------------------------------------------

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|

Re: Can Be Matched As

Seyed H. HAERI (Hossein)
In reply to this post by Naftoli Gugenheim
Hi Naftoli (and all others),

> The compiler complains,
>
> /tmp/test.scala:5: warning: abstract type pattern t.this.T is unchecked
> since it is eliminated by erasure
>   def test(a: Any): Unit = a match {case T(i) => println("")}
<snip>
> (The first warning sounds like a compiler bug.)

It looks like you're right. I say so because for

trait t {
  type B
  type T1 <: B
  type T2 <: B

  def t1_extr: T1 => Option[Int]
  def t2_extr: T2 => Option[(B, B)]

  object T1 {def unapply(t1: T1) = t1_extr(t1)}
  object T2 {def unapply(t2: T2) = t2_extr(t2)}

  def fun_with_three: B => Int = {
    case T1(i) => i * 3
    case T2(b1, b2) => (fun_with_three(b1) - 3) * (fun_with_three(b2) + 3)
  }
}

I get the same erasure warning message. But, then, given

object o extends t {
  class Base
  case class C1(i: Int) extends Base
  case class C2(l: Base, r: Base) extends Base

  type B = Base
  type T1 = C1
  type T2 = C2
  def t1_extr = C1.unapply
  def t2_extr = C2.unapply

  val c2 = C2(C1(10), C1(2))
  def run = fun_with_three(c2)
}

I get the following exception for "o.run":

java.lang.ClassCastException: test.o$C2 cannot be cast to test.o$C1
at test.o$$anonfun$t1_extr$1.apply(tester.scala:28)
at test.t$T1$.unapply(tester.scala:11)
at test.t$$anonfun$fun_with_three$1.apply(tester.scala:15)
at test.t$$anonfun$fun_with_three$1.apply(tester.scala:14)
at test.o$.run(tester.scala:32)
... 32 elided

It looks like the compiler (Scala 2.11.8 (Java HotSpot(TM) 64-Bit
Server VM, Java 1.8.0_121)) is mistakenly trying to shoehorn C2
instances into C1. And, the source of that seems to be the first match
statement of fun_with_three. Am I right in that that's a bug? How do I
overcome the problem anyway?

Cheers,
--Hossein

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.