我正在考虑在clojure和scala之间进行一些互操作。由于java本身现在有lambdas,我在考虑数据之间的泛化以及如何将函数应用于集合。
clojure.lang.IFn和generalises在clojure.lang.ISeq上的集合操作scala.Function和scala.collection.Traversable上的集合操作。java.util.function.Function,并在java.util.stream.Stream上扩展了集合操作。问题:
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中都有一些操作,它们接受集合,向集合应用函数并返回新集合。
我对clojure比较熟悉,所以有些操作如下:
(into {} [[:a 1] [:b 2]]) => {:a 1 :b 2}它将clojure向量转换为clojure映射。因为into操作是在java.util.List上通用的,所以可以使用继承java.util.List的任何数据结构。
我希望与clojure中的scala库一起工作,并面对某些障碍:
scala.Function,因此需要包装到clojure.lang.IFnjava.util.List继承,这意味着:
(into {} (scala-list [:a 1] [:b 2]))将无法工作。该功能看起来类似于:
(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]f:X->Y都是通用的。发布于 2018-09-24 16:13:39
我只能给你Haskell的答案,因为我不会说任何其他语言。然而,在我看来,您似乎主要是在寻找一种将输入自动转换为函数的方法。这似乎与单曲没有任何关系。
(concat (scala-list 1 2) [3 4]) => (scala-list 1 2 3 4)如果我把这个翻译成Haskell,我会给它这样的类型
concat :: (IsList l1, IsList l2) => l1 elem -> l2 elem -> [elem]其中ToList是一个类型类型,它将把这个容器转换成一个列表。
class IsListOf a where
toList :: a elem -> [elem]从您的示例中还不清楚如何决定输出类型,因此我无法帮助您。
(map + [1 2] (scala-list 3 4)) => [4 6]在Haskell中,这个函数不是map,而是zipWith。如果您想自动转换输入,可以这样做。
zipWith :: (IsList l1, IsList l2) => (a -> b -> c) -> l1 a -> l2 b -> [c]如果您想要自动转换函数,您也可以这样做。
zipWith :: (IsList l1, IsList l2, Is2Function f) => f a b c -> l1 a -> l2 b -> [c]Is2Function将再次成为一个只转换为2元函数的类型化类型。
class Is2Function f where
toFunction :: f a b c -> a -> b -> c关于泛化,也有一些需要记住的东西。我在前面说过,我不知道你将如何决定输出。这是编译器经常遇到的问题(至少在haskell中是这样)。概括从表面上看似乎不错,但它们并不总是使事情变得更清楚,并可能导致歧义。
发布于 2018-09-24 18:17:40
scala函数扩展了scala.Function和scala.collection.Traversable上的集合操作。 java扩展了java.util.function.Function,并在java.util.stream.Stream上扩展了集合操作。
首先,好消息是:这是不正确的,Java和Scala可以实现任何SAM (单一抽象方法)接口。这允许将Java与预期scala.FunctionN的API一起使用,而Scala使用期望java.util.function.*的API(包括Java )。这种互操作性应该在Scala2.12及更高版本中完成(据我所知)。
坏消息(您知道这即将到来):当具体谈到Scala集合API时,它也非常依赖于隐式参数,而这些参数在Java或Clojure中并不真正可用。类似地,Clojure集合API依赖于动态类型,而IFn不是SAM类型(因为它涵盖了具有不同数量的参数的函数)。当然,对于Clojure中的使用,Java和Scala之间的互操作没有帮助。
更普遍地说,3个集合API(如果算上Scala2.13中的重设计)可能太不同了,不可能像那样统一。
在这里,我看不出单子本身有什么用处。如果我试图从Clojure中执行一些有用的操作,我会使用“检查集合和函数类型,并在函数应用程序之前进行一些胁迫”作为解决方案。协议可以简化它,但需要一些性能成本。
https://stackoverflow.com/questions/52350969
复制相似问题