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

J. *_*Doe 1 monads haskell list

作为haskell的新手,我想知道更有效的方法是:

mapmulti :: (a -> [b]) -> [a] -> [b]
mapmulti fn list = concat $ map fn list
Run Code Online (Sandbox Code Playgroud)

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

或者并且优选地,是否存在一些更通用(可能是monadic)的方式让haskell从函数的结果中逐步创建列表,以便逐步构建列表而不创建O(n)要评估的大小的递归表达式树?

chi*_*chi 6

只是用

mapmulti = concatMap
Run Code Online (Sandbox Code Playgroud)

来自图书馆.

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

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

  • @ J.Doe,优秀的制作人使用GHC知道如何与优秀消费者融合的功能编写.基本的好生产者是`build`和`augment`,但你通常不直接使用它们.使用`replicate`,`iterate`,`unfoldr`(最新版本),`map`,`filter`,list comprehensions和numeric range. (4认同)
  • 砍伐森林是否发生在很大程度上取决于传递给`concatMap`的功能.除非它是一个"好的制作人",否则将分配列表,但可能会立即释放. (2认同)
  • 砍伐森林还需要非零优化设置(因此在GHCi中不会发生). (2认同)