gpt4 book ai didi

scala - 如果函数可以是不同的类型,单子(monad)规则将如何应用

转载 作者:行者123 更新时间:2023-12-02 02:14:48 27 4
gpt4 key购买 nike

我正在考虑在 clojure 和 scala 之间进行一些互操作。由于 java 本身现在有 lambda,我正在考虑数据之间的泛化以及如何将函数应用于集合

  • clojure 函数扩展 clojure.lang.IFn并概括了 clojure.lang.ISeq 上的收集操作
  • scala 函数扩展 scala.Function并概括了 scala.collection.Traversable 上的收集操作
  • java lambda 扩展 java.util.function.Function并概括了 java.util.stream.Stream 上的收集操作

  • 问题:
  • 单子(monad)在这种情况下有用吗?
  • 如果是这样,map操作可以在所有集合类型中实现,这如何通用?

  • 例子:
      (map (scala-fn +) 
    [1 2 3]
    (scala-seq [1 2 3])
    (.stream [1 2 3]))
    => (scala-seq [3 6 9])

    (添加haskell作为标签,以防人们可能知道铁杆类型)

    Clojure、Scala 和 Java 中都有一些操作,它们接受一个集合,将一个函数应用于该集合并返回一个新集合。
  • 所有这些语言都在 JVM 上运行。
  • 但是,每种语言都定义了自己的类来表示一个函数。

  • 我对clojure比较熟悉,所以有如下操作:
     (into {} [[:a 1] [:b 2]]) => {:a 1 :b 2}

    它将 clojure 向量转换为 clojure 映射。因为 into操作概括 java.util.List任何继承 java.util.List 的数据结构可以使用。

    我希望使用 clojure 中的一些 scala 库并面临某些障碍:
  • Scala 和 clojure 一样也有不可变的数据结构,但它们的定义与 clojure 数据结构大不相同
  • Scala 函数继承自 scala.Function所以需要包裹到clojure.lang.IFn
  • Scala 数据结构不继承自 java.util.List意思就是:
    (into {} (scala-list [:a 1] [:b 2]))不管用。
  • 我希望重新实现一些基本的 clojure 函数,这些函数也包含 scala 数据结构。 (map、reduce、mapcat 等...)

  • 该功能看起来像:
     (into {} (scala-list [:a 1] [:b 2])) => {:a 1 :b 2}

    (into (scala-map) [[:a 1] [:b 2]]) => (scala-map :a 1 :b 2)

    (concat (scala-list 1 2) [3 4]) => (scala-list 1 2 3 4)

    (concat [1 2] (scala-list 3 4)) => (1 2 3 4) ;lazy seq

    (map + [1 2] (scala-list 3 4)) => [4 6]

    (map (scala-fn +) [1 2] (scala-list 3 4)) => [4 6]
  • 我正在寻找的是在收集操作中同时使用 clojure 和 scala 函数的能力。
  • 我可以在不使用 monad 的情况下做到这一点(通过检查集合和函数类型并在函数应用之前进行一些强制)
  • 我在这里问的问题对我来说有点好奇,因为我读过的所有关于 monad 的文献似乎都假定任何函数 f:X->Y是通用的。
  • 但是,在 clojure/scala/lambda 互操作的情况下,clojure 函数、scala 函数和 java lambda 不是通用的。我很好奇如何使用范畴论来解决这个问题。
  • 最佳答案

    scala functions extend scala.Function and generalises collection operations on scala.collection.Traversable

    java lambdas extend java.util.function.Function and generalises collection operations on java.util.stream.Stream


    首先,好消息:这是不正确的,Java 和 Scala lambda 可以实现任何 SAM(单一抽象方法)接口(interface)。这允许将 Java lambdas 与期望 scala.FunctionN 的 API 一起使用。和带有 API 的 Scala lambdas 期望 java.util.function.* (包括 Java 流)。这种互操作性应该在 Scala 2.12 及更高版本中完成(据我所知)。
    坏消息(你知道这即将到来):当专门谈论 Scala 集合 API 时,它也非常依赖隐式参数,而这些参数在 Java 或 Clojure 中并不真正可用。同样,Clojure 集合 API 依赖于动态类型, IFn不是 SAM 类型(因为它涵盖了具有不同数量参数的函数)。当然,对于 Clojure 的使用,Java 和 Scala lambda 之间的互操作也无济于事。
    更一般地说,这 3 个集合 API(如果算上 Scala 2.13 中的重新设计,则为 4 个)可能相差太大而无法像这样统一。
    我看不出单子(monad)本身在这里有什么用处。如果我试图从 Clojure 做一些可用的事情,我会选择“检查集合和函数类型并在函数应用之前做一些强制”作为解决方案。 Protocols可以简化它,但会带来一些性能成本。

    关于scala - 如果函数可以是不同的类型,单子(monad)规则将如何应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52350969/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com