Unary type view

59 views
Skip to first unread message

Ka Ter

unread,
May 14, 2013, 8:36:57 AM5/14/13
to scala-l...@googlegroups.com
Hi,

I have problems understanding Scala's type system. Why does the
following code not compile in the line 'val z = ...'?

trait Unary[U[_], A]

case class A[T](t: T)
case class B[I[_], A](i: I[A]) extends Unary[({type O[X] = B[I, X]})#O, A]

def unary[MA <: Unary[U, A], U[_], A](ma: MA with Unary[U, A]): U[A] =
ma.asInstanceOf[U[A]]

val a = A(5)
val b = B(a)
val z = unary(b)

I get the error message: Multiple markers at this line
- type mismatch; found : B[A(in method
monadicAndMonadicStackSelection),Int] required: MA with
Unary[U,A(in method unary)]
- no type parameters for method unary: (ma: MA with Unary[U,A])U[A]
exist so that it can be applied to
arguments (B[A,Int]) --- because --- argument expression's type is
not compatible with formal parameter type;
found : B[A,Int] required: ?MA with Unary[?U,?A]

I don't understand why Scala cannot match the types. B is of type Unary.

I expect the type of z to be ({type O[X] = B[A, X})#O[Int]. I know that
I can achieve that using scalaz's Unapply type class, but I don't
understand why my solution should not work either.

Any thoughts?

--
Best Regards

Ka Ter

Paul Phillips

unread,
May 14, 2013, 10:26:00 AM5/14/13
to scala-l...@googlegroups.com

On Tue, May 14, 2013 at 5:36 AM, Ka Ter <ter....@googlemail.com> wrote:
I have problems understanding Scala's type system. Why does the
following code not compile in the line 'val z = ...'?

Probably because type lambdas aren't a first-class construct and it's a wonder they work as well as they do. No code inside the compiler has ever been written with type lambdas in mind (except maybe by jason) and it's not the world's most robust piece of software even when we're talking about the parts people did have in mind. Type projections in general, even simple ones, are full of bugs.

Jason Zaugg

unread,
May 15, 2013, 2:04:02 AM5/15/13
to scala-l...@googlegroups.com
On Tue, May 14, 2013 at 2:36 PM, Ka Ter <ter....@googlemail.com> wrote:
I have problems understanding Scala's type system. Why does the
following code not compile in the line 'val z = ...'?


I expect the type of z to be ({type O[X] = B[A, X})#O[Int]. I know that
I can achieve that using scalaz's Unapply type class, but I don't
understand why my solution should not work either.

Scala won't infer the partially applied type constructor. This is SI-2712.

Simplified:

scala> class M[_[_]]
warning: there were 1 feature warnings; re-run with -feature for details
defined class M

scala> class N extends M[({type l[a]=(a, Any)})#l]
defined class N

scala> def foo[N[_], A](mna: M[N[A]]) = {}
<console>:9: error: N[A] takes no type parameters, expected: one
       def foo[N[_], A](mna: M[N[A]]) = {}
                               ^

scala> def foo[N[_]](mna: M[N]) = {}
warning: there were 1 feature warnings; re-run with -feature for details
foo: [N[_]](mna: M[N])Unit

scala> foo(new N)
<console>:11: error: no type parameters for method foo: (mna: M[N])Unit exist so that it can be applied to arguments (N)

You can hold the hand of the type inferencer by defining a type alias (the alias in the type lambda is effectively anonymous, so doesn't cut the mustard...):

scala> type l[a]=(a, Any)
defined type alias l

scala> class N extends M[l]
defined class N

scala> foo(new N) 

-jason

Reply all
Reply to author
Forward
0 new messages