【问题标题】:Map, where each input element can correspond to multiple output elementsMap,其中每个输入元素可以对应多个输出元素
【发布时间】:2015-10-25 19:52:31
【问题描述】:

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

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

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

另外,最好是,有一些更通用(可能是单子)的方法让 haskell 从函数的结果逐步创建列表,以便在不创建 O(n) 大小的递归表达式树的情况下逐步构建列表来评估?

【问题讨论】:

    标签: list haskell monads


    【解决方案1】:

    随便用

    mapmulti = concatMap
    

    来自图书馆。

    此外,即使使用您自己的实现,编译器也可以使用称为“森林砍伐”的技术优化中间列表。

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

    【讨论】:

    • 森林砍伐是否发生在很大程度上取决于传递给concatMap 的函数。除非它是一个“好的生产者”,否则列表 conses 将被分配,但可能会立即释放。
    • @J.Doe,好的生产者是使用 GHC 知道如何与好的消费者融合的函数编写的。基本好的生产者是buildaugment,但你通常不直接使用它们。使用replicateiterateunfoldr(最新版本)、mapfilter、列表推导和数字范围。
    • 森林砍伐还需要非零优化设置(因此不会在 GHCi 中发生)。
    猜你喜欢
    • 1970-01-01
    • 2016-04-04
    • 2015-12-02
    • 2020-09-18
    • 2021-04-07
    • 2020-03-12
    • 2015-03-26
    • 2011-09-17
    • 1970-01-01
    相关资源
    最近更新 更多