While Bind (SelectMany) and Fold (Aggregate) are pretty similar, there is a slightly different point of view...
Matthew's Concat uses recursive aggregate and function as accumulator value.
To replace Bind we need many aggregates... (or do we, maybe not?)
By default, Aggregate/fold will exit the monad (so we "reify" (=execute), get the side effects and break the continuation)
By using func here, we can remain the continuation.
But still we kind of exit and enter the monad many times, which could affect the performance.
Bind is not totally "pure" as outer function will produce set of results but the outer function doesn't actually know (by type syntax) how to combine different results produced by the inner function. So it has to know something about these results that the function syntax won't tell us.
In theory Bind could match without running through items. Then it would be different. See this short video. Maybe do the concatenation without creating a new instance... (or with immutable data structures this means just using the pointer to old when creating a "new" one). This way we could get e.g. effective parallel execution. I think the current implementations, when they flatten, can reuse items but not the inner collections (/monads).