Scala中的多个flatMaps
而不是xs map f map g,写xs map {x => g(f(x))},类似地用于多个过滤操作.
如果我连续有两个或更多个flatMaps,有没有办法将它们组合成一个,这可能更有效?例如 def f(x: String) = Set(x,x.reverse) def g(x: String) = Set(x,x.toUpperCase) Set("hi","bye") flatMap f flatMap g // Set(bye,eyb,IH,BYE,EYB,ih,hi,HI) 解决方法
为了进行这样的转换,我们需要使用操作所具有的一些标识.例如,正如您所写,map具有标识
map f ° map g ≡ map (f ° g) (其中°代表函数组成 – 见Function1.compose(…);≡代表表达式的等价).这是因为带有map的类可以被视为functors,因此map的任何合理实现都必须保留此属性. 另一方面,具有flatMap并且如何创建某种单元素实例(如创建单例集合)的类通常形成monad.因此我们可以尝试从monad规则中推导出一些变换.但是我们可以为flatMap的重复应用推断出唯一的身份 (set flatMap f) flatMap g ≡ x flatMap { y => f(y) flatMap g } 这是一种用于flatMap组合的associativity relationship.这对优化计算没有多大帮助(实际上它可能会使情况变得更糟).因此,结论是,flatMap没有类似的一般“优化”身份. 底线是:给Set.flatMap的每个函数为它应用的每个元素创建一个新的Set.除非我们完全忘记使用组合flatMap并以某种不同的方式解决问题,否则我们无法避免创建这样的中间集.通常这是不值得的,因为组合flatMaps(或使用for(…)yield ..)更清晰,更易读,而且速度权衡很少通常不是一个大问题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |