为什么 >>= 比 concatMap 快,而它们应该是同一件事?

Why is >>= faster than concatMap when they ought to be the same thing?

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

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

在 base 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)