4

所以基本上我想写可以写成这样的功能:斯卡拉不处理不显式类型为封“:”功能

{ println(_) } =: thing 

在这里,我希望它实际上做thing.=:(println(_))。比方说,为求论点,即=:具有以下实现:

def =:(block : Int => Any) { 
    block(5) 
} 

所以我尝试调用它上面的方法,我也得到:

<console>:10: error: type mismatch; 
    found : Unit 
    required: Int => Any 
      println(_) =: thing 

我再试试这样做:

thing.=:(println(_)) 

这样我就能得到一个很好的5打印到终端。然后我试了这个:

{ value => println(value) } =: thing 

这又失败了,并告诉我有一个“缺少参数类型”。我猜这是因为Scala试图在这种情况下首先解析/编译函数参数,并且当它被称为更传统的方式时(不知道它是什么类型)(我完全猜到了)点运算符)。

任何人都可以在这里发现更多的问题,也可能建议实现某些东西接近我最初的目标的最佳方式?

P.S.对于标题感到抱歉。一旦我对问题有了更好的理解,我会重新命名它。

回答

6

类型推理从左到右工作,即使#:表单的符号方法名称最终从右到左工作。您可以使用一个辅助方法,如果你真的只有一个类型:

def let(fi: Int => Any) = fi 
case class Thing(i: Int) { 
    def =:(f: Int => Any) = f(i) 
} 

scala> let(_+2) =: Thing(5) 
res4: Any = 7 

但是这并不是一个完全令人满意的解决办法,如果你有很多可能的类型签名,因为你必须在左边匹配的辅助方法名所需的类型在右侧。

+0

无论如何要用隐式函数来实现这个吗?我猜不是因为Scala不会寻找隐含的,因为没有类型而不是错配。此外,如果你知道一个原因,你可以添加到你的答案,为什么类型推断不能正确地左对这些功能。 – seadowg

+0

@Oetzi - 将类型推理器从右向左工作会更有帮助。原则上没有理由不能做到这一点;它只是实施的一个限制。 –

1

那么,为什么你不加参数类型:

{ value:Int => println(value) } =: thing 

我不是一个专家斯卡拉自己,所以我不能提供什么样的inferencer可以在无法推断更深的解释。

+0

这样做的工作,但我正在写一个DSL,其中每个关闭将具有相同的输入类型,所以它会相当单调。 – seadowg