Map,其中每个输入元素可以对应多个输出元素

Map, where each input element can correspond to multiple output elements

作为 haskell 的新手,我想知道执行以下操作的更有效方法是什么:

mapmulti :: (a -> [b]) -> [a] -> [b]
mapmulti fn list = concat $ map fn list

我的列表将有数千到数百万个元素,创建一个包含 N 个列表的列表只是为了将它们连接在一起似乎是一种耻辱。

或者更好的是,是否有一些更通用的(可能是单子的)方法让 haskell 从函数的结果逐步创建列表,这样列表就可以逐步构建而不创建 O(n) 要评估的递归表达式树的大小?

只需使用

mapmulti = concatMap

来自图书馆。

此外,即使使用您自己的实现,编译器也可以使用称为 "deforestation" 的技术优化中间列表。

即使不这样做,由于 Haskell 是惰性的,在运行时中间列表在被消费之前也不会完全生成。相反,将生成一个列表元素并立即使用它,使其在生成下一个元素之前可用于垃圾回收。这将大大改善内存占用,因为一切都可以在常量 space.

中完成