【问题标题】:Why is >>= faster than concatMap when they ought to be the same thing?当它们应该是相同的东西时,为什么 >>= 比 concatMap 快?
【发布时间】:2015-11-06 18:12:25
【问题描述】:

昨晚,我正在编写一些娱乐性代码,在某个时候,我将 concatMap 替换为 >>= 并看到我的代码加速了约 10%。

我的印象是>>=[] 的定义正是concatMap,所以我有点困惑。

【问题讨论】:

    标签: performance list haskell ghc


    【解决方案1】:

    在基础 4.8 中,(>>=) 被实现(参见here)为:

    xs >>= f = [y | x <- xs, y <- f x]
    

    concatMap 正在使用更复杂的构建器(来源here

    concatMap :: Foldable t => (a -> [b]) -> t a -> [b]
    concatMap f xs = build (\c n -> foldr (\x b -> foldr c b (f x)) n xs)
    

    【讨论】:

    • 有趣。我不禁认为Foldable 也是Alternative 等同于Monad....
    • @AJFarmar 你为什么会这样想?我不知道这有什么意义
    • @user3217013 bind' fa f = foldr (&lt;|&gt;) empty $ foldr (:) [] (fmap f fa) 其中bind' :: (Foldable f, Applicative f) =&gt; f a -&gt; (a -&gt; f b) -&gt; f b。 QED。
    • @AJFarmar 可能foldr (:) [] 抛弃了被折叠事物的所有结构,因此bind' m return === m 对许多其他守法的Foldable+Alternatives 来说失败了。即使您跳过它并定义bind' fa f = foldr (&lt;|&gt;) empty (fmap f fa),我也会有同样的担忧——foldr (&lt;|&gt;) empty v 的“形状”可能与v 不同。
    • @erdeszt 当t 被称为[] 时,为什么concatMap 不专门用于更高效的版本? (也许只是图书馆作者的疏忽?)
    猜你喜欢
    • 1970-01-01
    • 2022-07-06
    • 2012-07-21
    • 1970-01-01
    • 2010-10-13
    • 2013-09-20
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    相关资源
    最近更新 更多