This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Why do I need to be verbose with this PartialFunction?

4 replies
Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.

hi,

i have the following problem with scala 2.8.0.RC6. this is my object:

object Ref {
def apply[ @specialized T ]( initialValue: T, cleanUp: PartialFunction[ T, Unit ])
( implicit m: ClassManifest[ T ]) : Ref[ T ] =
new CleanUpImpl( CRef( initialValue ), cleanUp )
}

and this is trying to use it:

private val useCount : Ref[ Int ] = Ref.apply[ Int ]( 0, { case 0 => bus.free})

which produces the following compiler error:

error: missing parameter type for expanded function ((x0$1) => x0$1 match {
case 0 => bus.free
})
private val useCount : Ref[ Int ] = Ref.apply[ Int ]( 0, { case 0 => bus.free})

i can do this:

private val useCount = Ref( 0, (i: Int) => i match { case 0 => bus.free })

by i don't understand why the compiler has problems with the type....?

thanks, -sciss-

Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.
Re: Why do I need to be verbose with this PartialFunction?

this is actually an overloading problem:

Ref has these:

object Ref {
def make[ @specialized T ]( implicit m: ClassManifest[ T ]) : Ref[ T ] =
new Impl( CRef.make[ T ])

def apply[ @specialized T ]( initialValue: T )( implicit m: ClassManifest[ T ]) : Ref[ T ] =
new Impl( CRef( initialValue ))

def apply[ @specialized T ]( initialValue: T, cleanUp: PartialFunction[ T, Unit ])
( implicit m: ClassManifest[ T ]) : Ref[ T ] =
new CleanUpImpl( CRef( initialValue ), cleanUp )

// ...
}

now if i change

(1)
private val useCount = Ref( 0, (i: Int) => i match { case 0 => bus.free })

to

(2)
private val useCount : Ref[ Int ] = Ref.apply( 0, (i: Int) => i match { case 0 => bus.free })

i get

error: too many arguments for method apply: (initialValue: T)(implicit m: ClassManifest[T])de.sciss.synth.proc.Ref[T] in object Ref
private val useCount : Ref[ Int ] = Ref.apply( 0, (i: Int) => i match { case 0 => bus.free })

so it doesn't see the second "apply" method. what it exactly does in variant (1) i don't know, only that useCount is of type (Int, (Int) => Unit) ??

i checked, i have no other symbol named Ref in my scope, so there is no problem with conflicting names. if i rename the second method to applyX and use do

private val useCount = Ref.applyX( 0, (i: Int) => i match { case 0 => bus.free })

everything behaves as expected.

i'm baffled....

best, -sciss-

Am 24.06.2010 um 16:12 schrieb Sciss:

> hi,
>
> i have the following problem with scala 2.8.0.RC6. this is my object:
>
> object Ref {
> def apply[ @specialized T ]( initialValue: T, cleanUp: PartialFunction[ T, Unit ])
> ( implicit m: ClassManifest[ T ]) : Ref[ T ] =
> new CleanUpImpl( CRef( initialValue ), cleanUp )
> }
>
> and this is trying to use it:
>
> private val useCount : Ref[ Int ] = Ref.apply[ Int ]( 0, { case 0 => bus.free})
>
> which produces the following compiler error:
>
> error: missing parameter type for expanded function ((x0$1) => x0$1 match {
> case 0 => bus.free
> })
> private val useCount : Ref[ Int ] = Ref.apply[ Int ]( 0, { case 0 => bus.free})
>
> i can do this:
>
> private val useCount = Ref( 0, (i: Int) => i match { case 0 => bus.free })
>
> by i don't understand why the compiler has problems with the type....?
>
> thanks, -sciss-
>

Jason Zaugg
Joined: 2009-05-18,
User offline. Last seen 38 weeks 5 days ago.
Re: Why do I need to be verbose with this PartialFunction?

If there are more than one overloaded method alternatives that are
potentially applicable to an argument list, the arguments are typed
without an expected type.

Consequently, you need to explicitly type the parameters of anonymous
functions, and you cannot use pattern matching anonymous functions, as
these require that the expected type is at least partially defined.

I'm not sure if this is the exact problem you're encountering as your
example is a bit cluttered, but it might be a starting point for you
to figure things out.

-jason

scala> def bar(f: Int => Int) = 0
bar: (f: (Int) => Int)Int

scala> bar((i) => i)
res5: Int = 0

scala> bar { case i => i }
res2: Int = 0

scala> object ol { def foo(a: Any) = 0; def foo(f: Int => Int) = 0}
defined module ol

scala> ol.foo { case i => i }
:7: error: missing parameter type for expanded function ((x0$1) => x0$1
match {
case (i @ _) => i
})
ol.foo { case i => i }
^
scala> ol.foo { i => i }
:7: error: missing parameter type
ol.foo { i => i }
^
scala> ol.foo { (i: Int) => i }
res4: Int = 0

On Thu, Jun 24, 2010 at 5:23 PM, Sciss wrote:
> this is actually an overloading problem:
> Am 24.06.2010 um 16:12 schrieb Sciss:
>
>> hi,
>>
>> i have the following problem with scala 2.8.0.RC6. this is my object:
>>
>> object Ref {
>>   def apply[ @specialized T ]( initialValue: T, cleanUp: PartialFunction[ T, Unit ])
>>                              ( implicit m: ClassManifest[ T ]) : Ref[ T ] =
>>      new CleanUpImpl( CRef( initialValue ), cleanUp )
>> }
>>
>> and this is trying to use it:
>>
>>       private val useCount : Ref[ Int ] = Ref.apply[ Int ]( 0, { case 0 => bus.free})
>>
>> which produces the following compiler error:
>>
>>       error: missing parameter type for expanded function ((x0$1) => x0$1 match {
>>       case 0 => bus.free
>>       })
>>       private val useCount : Ref[ Int ] = Ref.apply[ Int ]( 0, { case 0 => bus.free})
>>
>> i can do this:
>>
>>      private val useCount = Ref( 0, (i: Int) => i match { case 0 => bus.free })
>>
>> by i don't understand why the compiler has problems with the type....?
>>
>> thanks, -sciss-
>>
>
>

Arthur Peters 2
Joined: 2009-01-10,
User offline. Last seen 42 years 45 weeks ago.
Re: Why do I need to be verbose with this PartialFunction?

One way to get around this problem is to but the function in a separate parameter list. That way the type T will be infered based on the first argument and therefore known when the function is being typed.

It also arguably improves the syntax. You can write foo(0) { case v => ... }

-Arthur (sent from phone)

On Jun 24, 2010 12:06 PM, "Jason Zaugg" <jzaugg@gmail.com> wrote:

If there are more than one overloaded method alternatives that are
potentially applicable to an argument list, the arguments are typed
without an expected type.

Consequently, you need to explicitly type the parameters of anonymous
functions, and you cannot use pattern matching anonymous functions, as
these require that the expected type is at least partially defined.

I'm not sure if this is the exact problem you're encountering as your
example is a bit cluttered, but it might be a starting point for you
to figure things out.

-jason


scala> def bar(f: Int => Int) = 0
bar: (f: (Int) => Int)Int

scala> bar((i) => i)
res5: Int = 0

scala> bar { case i => i }
res2: Int = 0

scala> object ol { def foo(a: Any) = 0; def foo(f: Int => Int) = 0}
defined module ol

scala> ol.foo { case i => i }
<console>:7: error: missing parameter type for expanded function ((x0$1) => x0$1
 match {
 case (i @ _) => i
})
      ol.foo { case i => i }
             ^
scala> ol.foo { i => i }
<console>:7: error: missing parameter type
      ol.foo { i => i }
               ^
scala> ol.foo { (i: Int) => i }
res4: Int = 0



On Thu, Jun 24, 2010 at 5:23 PM, Sciss <contact@sciss.de> wrote:
> this is actually an overloading...

> Am 24.06.2010 um 16:12 schrieb Sciss:
>
>> hi,
>>
>> i have the following problem with scala 2.8.0...

Sciss
Joined: 2008-12-17,
User offline. Last seen 28 weeks 5 days ago.
Re: Why do I need to be verbose with this PartialFunction?

hi jason, hi arthur,

the problem is really some weird overloading behaviour (actually looking like a bug to me), as renaming the apply method to some other made it work completely flawlessly:

object Ref {
def apply[ @specialized T ]( initialValue: T )( implicit m: ClassManifest[ T ]) : Ref[ T ] = ...

// SCALA BUG : CANNOT OVERLOAD
// def apply[ @specialized T ]( initialValue: T, cleanUp: PartialFunction[ T, Unit ])
// ( implicit m: ClassManifest[ T ]) : Ref[ T ] =

def withCheck[ @specialized T ]( initialValue: T )( cleanUp: PartialFunction[ T, Unit ])
( implicit m: ClassManifest[ T ]) : Ref[ T ] = ...
}

val useCount = Ref.withCheck( 0 ) { case 0 => bus.free } // works!

you see, i also put the function again in a separate arg list (i had undone that when trying to chase the error).

best, -sciss-

Am 25.06.2010 um 00:16 schrieb Arthur Peters:

> One way to get around this problem is to but the function in a separate parameter list. That way the type T will be infered based on the first argument and therefore known when the function is being typed.
>
> It also arguably improves the syntax. You can write foo(0) { case v => ... }
>
> -Arthur (sent from phone)
>
>
>> On Jun 24, 2010 12:06 PM, "Jason Zaugg" wrote:
>>
>> If there are more than one overloaded method alternatives that are
>> potentially applicable to an argument list, the arguments are typed
>> without an expected type.
>>
>> Consequently, you need to explicitly type the parameters of anonymous
>> functions, and you cannot use pattern matching anonymous functions, as
>> these require that the expected type is at least partially defined.
>>
>> I'm not sure if this is the exact problem you're encountering as your
>> example is a bit cluttered, but it might be a starting point for you
>> to figure things out.
>>
>> -jason
>>
>>
>> scala> def bar(f: Int => Int) = 0
>> bar: (f: (Int) => Int)Int
>>
>> scala> bar((i) => i)
>> res5: Int = 0
>>
>> scala> bar { case i => i }
>> res2: Int = 0
>>
>> scala> object ol { def foo(a: Any) = 0; def foo(f: Int => Int) = 0}
>> defined module ol
>>
>> scala> ol.foo { case i => i }
>> :7: error: missing parameter type for expanded function ((x0$1) => x0$1
>> match {
>> case (i @ _) => i
>> })
>> ol.foo { case i => i }
>> ^
>> scala> ol.foo { i => i }
>> :7: error: missing parameter type
>> ol.foo { i => i }
>> ^
>> scala> ol.foo { (i: Int) => i }
>> res4: Int = 0
>>
>>
>> On Thu, Jun 24, 2010 at 5:23 PM, Sciss wrote:
>> > this is actually an overloading...
>>
>> > Am 24.06.2010 um 16:12 schrieb Sciss:
>> >
>> >> hi,
>> >>
>> >> i have the following problem with scala 2.8.0...
>>
>

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland