gpt4 book ai didi

scala - 斯卡拉结合笛卡尔乘积和 map

转载 作者:行者123 更新时间:2023-12-04 13:21:07 25 4
gpt4 key购买 nike

这是对Expand a Set of Sets of Strings into Cartesian Product in Scala的跟进

这个想法是你想采取:

val sets = Set(Set("a","b","c"), Set("1","2"), Set("S","T"))

然后回来:
Set("a&1&S", "a&1&T", "a&2&S", ..., "c&2&T")

一个通用的解决方案是:
def combine[A](f:(A, A) => A)(xs:Iterable[Iterable[A]]) =
xs.reduceLeft { (x, y) => x.view.flatMap {a => y.map(f(a, _)) } }

用法如下:
val expanded = combine{(x:String, y:String) => x + "&" + y}(sets).toSet

从理论上讲,应该有一种方法可以接收 Set[Set[A]]类型的输入并取回 Set[B]。即,在组合元素的同时转换类型。

一个示例用法是采用字符串集(如上)并输出它们的串联长度。 f中的 combine函数的形式如下:
(a:Int, b:String) => a + b.length 

我无法提出实现方案。有人有答案吗?

最佳答案

如果您确实希望组合器函数进行映射,则可以使用fold,但作为Craig pointed out,您必须提供一个种子值:

def combine[A, B](f: B => A => B, zero: B)(xs: Iterable[Iterable[A]]) =         
xs.foldLeft(Iterable(zero)) {
(x, y) => x.view flatMap { y map f(_) }
}

您需要这样的种子值的事实来自组合器/映射器函数类型 (B, A) => B(或者,作为 curry 函数 B => A => B)。显然,要映射遇到的第一个 A,您将需要提供 B

您可以使用 Zero类型类使调用者更简单一些:
trait Zero[T] {
def zero: T
}
object Zero {
implicit object IntHasZero extends Zero[Int] {
val zero = 0
}
// ... etc ...
}

然后可以将 combine方法定义为:
def combine[A, B : Zero](f: B => A => B)(xs: Iterable[Iterable[A]]) =         
xs.foldLeft(Iterable(implicitly[Zero[B]].zero)) {
(x, y) => x.view flatMap { y map f(_) }
}

用法:
combine((b: Int) => (a: String) => b + a.length)(sets)

Scalaz提供了 Zero类型类,以及许多其他用于函数式编程的东西。

关于scala - 斯卡拉结合笛卡尔乘积和 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4514333/

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