仅当要转换的函数具有至少两个参数时,函数才能隐式转换为二阶函数 [英] Implicit conversion of a function to a second-order-function only works if the function to convert has at least two parameters

查看:87
本文介绍了仅当要转换的函数具有至少两个参数时,函数才能隐式转换为二阶函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个隐式转换和高阶函数的问题.如果要转换的函数至少具有两个参数,则似乎只能将函数隐式转换为二阶函数.

I have a problem of implicit conversions and higher-order functions. It seems that an implicit conversions of a function to a second-order-function only works, if the function to convert has at least two parameters.

作品:

implicit def conv(foo: Integer => String): String => String = null

不起作用:

implicit def conv(foo: Integer => String): String => String => String = null

作品:

implicit def conv(foo: (Integer, Integer) => String): String => String => String = null

带有故障点的完整示例:

Full example with point of failure:

{
    implicit def conv(foo: Integer => String): String => String = null

    def baadf00d(foo: Integer): String = null

    def deadbeef(foo: String => String) = null

    deadbeef(conv(baadf00d))

    deadbeef(baadf00d)
}

{
    implicit def conv(foo: Integer => String): String => String => String = null

    def baadf00d(foo: Integer): String = null

    def deadbeef(foo: String => String => String) = null

    deadbeef(conv(baadf00d))

    deadbeef(baadf00d) // <-------- DOES NOT COMPILE!
}

{
    implicit def conv(foo: (Integer, Integer) => String): String => String => String = null

    def baadf00d(foo: Integer, bar: Integer): String = null

    def deadbeef(foo: String => String => String) = null

    deadbeef(conv(baadf00d))

    deadbeef(baadf00d)
}

我想念什么?

谢谢!

推荐答案

  implicit def conv(foo: Integer => String): String => String => String = ???

  def baadf00d(i: Integer): String = ???
  def goodf00d: Integer => String = _ => ???

  def deadbeef(foo: String => String => String) = ???

  deadbeef(conv(baadf00d))

  deadbeef(baadf00d) // <-------- DOES NOT COMPILE!
  deadbeef(goodf00d) // <-------- COMPILE!
  // ¯\_(ツ)_/¯

问题在于隐式转换如何在Scala上工作,以及Scala中存在咖喱函数和非咖喱函数的事实.

The issue is how implicit conversions work on Scala and the fact that there are curried and uncurried functions in Scala.

这应该是可行的,但不能成功,并且可能只是另一个编译器错误(随着越来越多地使用Scala,准备迎接更多的错误).

This is something that SHOULD work but doesn't and is probably just yet another compiler bug (get ready to meet many more as you use Scala more and more).

关于您的最后一个示例

implicit def conv(foo: (Integer, Integer) => String): String => String => String = null

def baadf00d(foo: Integer, bar: Integer): String = null

def deadbeef(foo: String => String => String) = null

那是因为函数定义确实匹配.转换函数期望在scala中有一个函数(Int, Int) => String和一个普通的方法定义(未使用),就像baadf00d的定义方式一样.

That's because there the function definitions do match. The conv expects a function (Int, Int) => String and a normal method definition (uncurried) in scala, like how baadf00d is defined, turns into that.

例如,一个函数

def f(a: Int, b: Int): String

变成了

(Int, Int) => String

请注意,两个Int已元组!这与以下不同:

Notice that the 2 Ints are tupled! This is NOT the same as:

Int => Int => String

如果要将baadf00d重新定义为:

If you were to redefine baadf00d into:

def baadf00d: Integer => Integer => String = _ => _ => ???

该代码将无法编译,因为baadf00d现在与众不同",即使它正在做相同的事情.

That code won't compile, because baadf00d is now "different", even though it is doing the same thing.

有关更多信息,请查看对象的定义:

For more information, look at the definition of the objects:

Function1, Function2, Function3 ....

http://www.scala-lang.org/api/current /#scala.Function2

这篇关于仅当要转换的函数具有至少两个参数时,函数才能隐式转换为二阶函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆