【问题标题】:How do I make lambda functions generic in Scala? [duplicate]如何在 Scala 中使 lambda 函数通用? [复制]
【发布时间】:2013-06-28 20:14:14
【问题描述】:

你们中的大多数人可能都知道在 scala 中可以通过两种方式定义函数,有 'def' 方法和 lambda 方法...

使 'def' 类通用是相当简单的

def someFunc[T](a: T) { // insert body here

我在这里遇到的问题是如何使以下通用:

val someFunc = (a: Int) => // insert body here

当然现在 a 是一个整数,但我需要做什么才能使其通用?

val someFunc[T] = (a: T) => 不起作用,val someFunc = [T](a: T) => 也不起作用

是否有可能使它们通用,或者我应该坚持使用“def”变体?

【问题讨论】:

  • 在 Scala 中定义函数有多种方式,但使用def 不是其中之一! def 关键字用于定义方法,这在某种意义上是JVM 的产物。给定合适的类型信息,Scala 可以自动将方法提升到相应的函数,使其透明且完全无摩擦,但两者是不同的东西。见stackoverflow.com/questions/17203510/…
  • google 一些与函数和 scala 有关的东西,我向你保证,大多数结果都会显示方法和人们将方法称为函数,因此会造成混淆
  • 尽管混淆是可以理解或解释的,但它并不能帮助从业者模糊区分。

标签: function scala generics lambda


【解决方案1】:

正如 Randall Schulz 所说,def 不是创建函数,而是创建方法。但是,它可以返回一个函数,这样您就可以创建通用函数,例如 Predef 中的 identity 函数。这看起来像这样:

def myId[A] = (a: A) => a

List(1,2,3) map myId
// List(1,2,3)

List("foo") map myId
// List("foo")

但请注意,在没有任何类型信息的情况下调用 myId 会推断出 Nothing。在上述情况下它可以工作,因为类型推断使用map 的签名,即map[B](f: A => B),其中A 是列表的类型,B 被推断为与A 相同,因为那是myId的签名。

【讨论】:

  • 我之前实际上是把它写成一个解决方案,但是我得到了关于它的 cmets 然后成为返回函数的函数,因此不是我想要的,然后我删除了它......但似乎我并不是唯一一个想出一种方法(很多人在 scala 中调用函数)然后返回一个函数的人
  • 如果方法没有副作用,它们本质上就等同于函数。在其他语言如 haskell 中,每个带参数的函数也返回函数,因为 haskell 中的每个函数都是柯里化的。实际上 myId 方法也是一个 curried 函数,就像您将整个事物创建为一个方法,然后使用 0 个给定参数部分应用它一样。
  • 我非常了解柯里化的概念;这个问题源于我试图用这种类型签名创建一个函数:(a -> b) -> (a, c) -> (b, c) 但为了简单起见,我将其保留为单个泛型类型而不是三个。如您所知,我展示的类型签名演示了一个接受 2 个参数并返回一个元组的函数,根据使用的参数数量,该函数要么返回元组,要么返回一个元组并返回一个元组。 ..所以是的,我很熟悉这个想法:)
  • 我认为这个答案归结为“坚持def”。
【解决方案2】:

我不相信这是可能的。您可以查看之前的这篇文章以了解更多详细信息:

How can I define an anonymous generic Scala function?

解决它的唯一方法(如答案之一所述)是扩展 FunctionX 之类的东西并在类级别使用泛型,然后在 apply 函数的覆盖中使用它。

【讨论】:

    【解决方案3】:

    我也不相信这可能,但我是个悲观主义者。

    http://www.chuusai.com/2012/04/27/shapeless-polymorphic-function-values-1/

    编辑:

    如果这不是您要的,请告诉我,但这就是为什么接受的答案不是我认为您要的,请参阅链接:

    scala> :pa
    // Entering paste mode (ctrl-D to finish)
    
    def myId[A] = (a: A) => a
    
    List(1,2,3) map myId
    // List(1,2,3)
    
    List("foo") map myId
    // List("foo")
    
    // Exiting paste mode, now interpreting.
    
    myId: [A]=> A => A
    res0: List[String] = List(foo)
    
    scala> val f1 = myId[Int]
    f1: Int => Int = <function1>
    
    scala> val f2 = myId[String]
    f2: String => String = <function1>
    
    scala> List(1,2,3) map f2
    <console>:10: error: type mismatch;
     found   : String => String
     required: Int => ?
                  List(1,2,3) map f2
                                  ^
    
    scala> List("foo") map f1
    <console>:10: error: type mismatch;
     found   : Int => Int
     required: String => ?
                  List("foo") map f1
                                  ^
    

    函数值不是多态的,即泛型的。

    【讨论】:

      【解决方案4】:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-02
        • 2020-05-30
        • 1970-01-01
        • 2018-05-03
        相关资源
        最近更新 更多