加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

是否可以将flip实现为Scala函数(而不是方法)

发布时间:2020-12-16 09:56:04 所属栏目:安全 来源:网络整理
导读:作为学习 Scala的一部分,我尝试在 Scala中实现Haskell的翻转函数(具有签名(A = B = C)=(B = A = C))的函数 – 并实现它作为一个函数(使用val)而不作为一个方法(使用def). 我可以将它实现为一种方法,例如这样: def flip[A,B,C](f: (A,B) = C):((B,A) = C) =
作为学习 Scala的一部分,我尝试在 Scala中实现Haskell的翻转函数(具有签名(A => B => C)=>(B => A => C))的函数 – 并实现它作为一个函数(使用val)而不作为一个方法(使用def).

我可以将它实现为一种方法,例如这样:

def flip[A,B,C](f: (A,B) => C):((B,A) => C) = (b: B,a: A) => f(a,b)
val minus = (a: Int,b: Int) => a - b
val f = flip(minus)
println(f(3,5))

但是,当我尝试将其作为函数实现时,它不起作用:

val flip = (f: ((Any,Any) => Any)) => ((a: Any,b: Any) => f(b,a))
val minus = (a: Int,5))

当我尝试编译此代码时,它会失败并显示以下消息:

Error:(8,18) type mismatch;
found   : (Int,Int) => Int
required: (Any,Any) => Any
val f = flip(minus)

我理解它失败的原因:我尝试传递(Int,Int)=> Int where(Any,Any)=>任何预期.但是,我不知道如何解决这个问题.有可能吗?

解决方法

与不同的方法不同,Scala不支持多态函数.这是由于函数的第一类值性质,它们只是函数特征的实例.这些函数是类,它们需要在声明站点绑定类型.

如果我们采用翻转方法并尝试将其扩展为函数,我们会看到:

val flipFn = flip _

我们将返回一个类型的值:

((Nothing,Nothing) => Nothing) => (Nothing,Nothing) => Nothing

由于没有绑定任何类型的事实,因此编译器会使用buttom类型Nothing.

然而,并非所有希望都失去了.有一个名为shapeless的库,它允许我们通过PolyN定义多态函数.

我们可以像这样实现翻转:

import shapeless.Poly1

object flip extends Poly1 {
  implicit def genericCase[A,C] = at[(A,B) => C](f => (b: B,b))
}

flip与FunctionN trait没有什么不同,它定义了一个将被调用的apply方法.

我们这样使用它:

def main(args: Array[String]): Unit = {
  val minus = (a: Int,b: Int) => a - b
  val f = flip(minus)
  println(f(3,5))
}

产量:

2

这也适用于String:

def main(args: Array[String]): Unit = {
  val stringConcat = (a: String,b: String) => a + b
  val f = flip(stringConcat)
  println(f("hello","world"))
}

产量:

worldhello

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读