首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >仅当要转换的函数至少有两个参数时,才能将函数隐式转换为二阶函数

仅当要转换的函数至少有两个参数时,才能将函数隐式转换为二阶函数
EN

Stack Overflow用户
提问于 2015-02-11 21:49:10
回答 2查看 446关注 0票数 7

我有一个隐式转换和高阶函数的问题。似乎只有当要转换的函数至少有两个参数时,函数到二阶函数的隐式转换才有效。

作品:

代码语言:javascript
复制
implicit def conv(foo: Integer => String): String => String = null

不起作用:

代码语言:javascript
复制
implicit def conv(foo: Integer => String): String => String => String = null

作品:

代码语言:javascript
复制
implicit def conv(foo: (Integer, Integer) => String): String => String => String = null

包含故障点的完整示例:

代码语言:javascript
复制
{
    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)
}

我遗漏了什么?

谢谢!

EN

回答 2

Stack Overflow用户

发布于 2015-02-12 08:57:40

代码语言:javascript
复制
  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中有curried和uncurried函数的事实。

这是一些应该可以工作但却不能工作的东西,而且可能只是另一个编译器错误(随着您越来越多地使用Scala,请准备好迎接更多的错误)。

编辑:对于您的上一个示例

代码语言:javascript
复制
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

这是因为函数定义确实是匹配的。conv期望一个函数(Int, Int) => String,而scala中的一个普通方法定义(非uncurried),就像baadf00d是如何定义的一样,变成了那样。

例如,一个函数:

代码语言:javascript
复制
def f(a: Int, b: Int): String

被转换成一个

代码语言:javascript
复制
(Int, Int) => String

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

代码语言:javascript
复制
Int => Int => String

如果要将baadf00d重新定义为:

代码语言:javascript
复制
def baadf00d: Integer => Integer => String = _ => _ => ???

这段代码不会编译,因为baadf00d现在是“不同的”,尽管它做的是相同的事情。

有关详细信息,请查看对象的定义:

代码语言:javascript
复制
Function1, Function2, Function3 ....

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

票数 3
EN

Stack Overflow用户

发布于 2015-02-11 22:35:10

代码语言:javascript
复制
implicit def conv1(a: Function1[Int, String]): Function2[String, String, String] = null
def baadf00d1(i: Int): String = null
def deadbeef1(arg: Function2[String, String, String]) = null  
deadbeef(baadf00d) // compiles

这是A => BFunction1[A,B]之间的转换没有发生。

Predef中还有一个Function类型--注意这里的类型差异:

代码语言:javascript
复制
scala> val f1: Function[Int, Int] = null
f1: Function[Int,Int] = null

scala> val f2: Function1[Int, Int] = null
f2: Int => Int = null

scala> :type f1
Function[Int,Int]

scala> :type f2
Int => Int

它是Function1的别名,但具有不同的类型界限(如下面的注释所指出的)。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28456012

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档