2016-03-01 125 views
1

我刚刚遇到一个奇怪的问题,而试图使用部分功能重载函数重载函数PartialFunction:斯卡拉:在参数

class Foo { 
    def bar(pf: PartialFunction[String, Int]): Foo = ??? 
    def bar(zd: Int): Foo = ??? 
    def zed(pf: PartialFunction[String, Int]): Foo = ??? 
} 

... 
new Foo() 
    .bar (0) 
    .zed { case _ => 1 } // this line is OK 
    .bar { case _ => 1 } // This line does not compile 

我已经贴在REPL这个代码,并获得一个奇怪的错误:

The argument types of an anonymous function must be fully known. (SLS 8.5) 
Expected type was: ? 
      .bar { case _ => 1 } 
       ^

我在网上查了,发现这个错误不同的解释,但不是一个谈论过载。据我所知,PartialFunction被扩展为匿名函数。因此,在这种情况下,这将导致类似:

object Test { 
    new Foo() 
    .bar (0) 
    .zed { case _ => 1 } 
    .bar { (x:String) => x match { case _ => 1 } } 
} 

但是,一旦在REPL粘贴,我得到另一个错误:

<console>:17: error: overloaded method value bar with alternatives: 
    (zd: Int)Foo <and> 
    (pf: PartialFunction[String,Int])Foo 
cannot be applied to (String => Int) 
      .bar { (x:String) => x match { case _ => 1 } } 
      ^

这很好,因为没有签名采取匿名在论证中起作用。那么我错过了什么?我是否错误地扩展了部分功能?

谢谢你的帮助!

编辑

我刚刚发现的问题可能来自歧义就应该叫哪种方法:

object Test { 
    new Foo() 
    .bar (0) 
    .zed { case _ => 1 } 
    .bar(PartialFunction({case _ => 1})) // This works 
} 

其次,我发现了一个有趣的类似的问题here

+2

不要使用重载 –

+0

好的,但有没有一个原因,为什么这是失败? –

回答

0

这是explication这个问题。似乎编译器无法解析匹配匿名函数的类型或模式。只是因为他们的“形状”无法解决。换句话说,重载不能用于PartialFunctions。

2

由于返璞词说,在你链接的地方,它不是一个局部的功能,但模式匹配匿名函数,它可以是一个PartialFunctionFunction取决于什么的预期,而问题是它不能推断类型,因为用于重载目的的类型检查arg没有“预期类型”。 “形状”测试可以让函数文字起作用。

scala> object X { def f(i: Int) = ??? ; def f(g: Int => Int) = ??? } 
defined object X 

scala> X.f { case i => 2 * i } 
<console>:13: error: missing parameter type for expanded function 
The argument types of an anonymous function must be fully known. (SLS 8.5) 
Expected type was: ? 
     X.f { case i => 2 * i } 
     ^

scala> X.f(i => 2 * i) 
scala.NotImplementedError: an implementation is missing 
    at scala.Predef$.$qmark$qmark$qmark(Predef.scala:230) 
    at X$.f(<console>:11) 
    ... 28 elided 

scala> X.f({ case i => 2 * i }: Int => Int) 
scala.NotImplementedError: an implementation is missing 
    at scala.Predef$.$qmark$qmark$qmark(Predef.scala:230) 
    at X$.f(<console>:11) 
    ... 28 elided