I think the responses you get here is largely due to the "language jumping" which instantly turns it into a language comparison.
If you'd stuck to one language, and implemented the "machinery" in that, it'd perhaps be clearer that the point wasn't C/Python/Ruby vs. Haskell.
E.g. here's a generic version in Ruby that to keep it simple just treats an Array as Maybe, with the empty Array as Nothing, giving us mappend and fromMaybe (we could make this more convoluted with a lazy "mappend" too, but it'd make the code even more un-Rubyish) like these:
def mappend(*args) args.map(&:call).compact; end
def fromMaybe(default); [yield].map{|m| m.empty? ? default : m}.first; end
And so fizzbuzz becomes:
def fizzbuzz(i)
fromMaybe([i]) {
mappend(
-> { i % 3 == 0 ? "Fizz" : nil },
-> { i % 5 == 0 ? "Buzz" : nil })
}
end
(1..100).each {|i| puts(fizzbuzz(i).join) }
And just as clear and extensible as the Haskell version.
I think the issue with using this as an example is compounded by making it one where you can make the lambda's generic over a simple hash lookup, as well, which makes it easy to overlook that the above can also handle more divergent rules (e.g. ones not relying on remainder, for example)