What are the differences between mapcat in Clojure and flatMap in Scala in terms of what they operate on?

后端 未结 4 1181
隐瞒了意图╮
隐瞒了意图╮ 2021-02-08 14:13

I understand the equivalent to flatMap in Scala is mapcat in Clojure.

I have an inkling that mapcat in clojure only works with sequences, unli

相关标签:
4条回答
  • 2021-02-08 14:29

    The real difference is that flatMap is polymorphic on the type, and mapcat isn't. So any type can decide to provide a "flatMap" like behaviour. That's how you get things like Futures being flatMapable.

    In Clojure, mapcat is specific to the seqable type. Any seqable can be coerced into a sequence, and all sequence can be mapped and concatenated. The mapcat implementation will check if the input is seqable, if so, it will call seq on it to coerce it to a sequence, and then it will map and cat that sequence and give you back a sequence. You don't get back a result of the original type.

    In Scala, if you implement IterableLike trait (I think that's the right interface), you get the default flatMap implementation which is a bit like the Clojure one minus the coercion to sequence. But, many types also provide a custom implementation of flatMap, making it generic in that way.

    0 讨论(0)
  • 2021-02-08 14:44

    I know a little about Scala but it seems to me flatMap is the Scala bind function in a monad and mapcat is a possible implementation of the bind function for the sequence monad in Clojure. So they are the same for sequences.

    But Scala for example has a flatMap function for Futures: it takes a future and a mapping function and returns a future that will complete after input future completes. This operation doesn't seem to be a simple mapcat in Clojure. It may be realized this way instead

    (defn flat-map [f mv] (mapcat (fn [v] (future (f @v))) mv))
    

    So, no. They are not the same, neither in terms of what they operate on. In Scala flatMap is the common name for different functions and for example Futures' flatMap coordinates input and output futures. A simple mapcat in Clojure won't work because it won't return a future.

    0 讨论(0)
  • 2021-02-08 14:50

    They seem very similar and appear to work on the same kind of things. From looking at the documentation and examples I can't see a functional difference.

    mapcat works on sequences, and just about every clojure data type can be a sequence. If you pass something that is not already a seq to mapcat it will call seq on it automatically, so in practice you can pass just about all clojure values to mapcat. If you want to iterate over a tree you would need to call prewalk or postwalk to specify the traversal order.

    0 讨论(0)
  • 2021-02-08 14:56

    In the standard Scala library: Responder, Future, Parser, ControlContext. None of them are sequences or particularly sequence-like. There is also a slight variation in ParseResult.

    0 讨论(0)
提交回复
热议问题