In Haskell we see Foldable and Traversable landing in Haskell prelude.
These both do operations on sequences.
Prelude Data.Sequence> map (\n -> replicate n 'a') [1,3,5]
["a","aaa","aaaaa"]
Prelude Data.Sequence> fmap (\n -> replicate n 'a') (1 <| 3 <| 5 <| empty)
fromList ["a","aaa","aaaaa"]
My question is is the equivalent of Haskell's Foldable and Traversable simply a sequence in Clojure?
Assumptions:
- I realise that the equivalent of fmap in Haskell is m-fmap in Clojure.
No. Whilst any kind of
Functor
representing finite sequences of elements will beTraversable
(henceFoldable
), there are plenty of other structures which areTraversable
, but which aren't sequence-like, in that they don't have an obvious notion of concatenation. There will be a way to obtain the sequence of contained elements, but the structure may consist of more than just that sequence.What
Traversable f
means, in effect, is that structures with typef x
contain finitely many elements of typex
, and that there is some way totraverse
the structure visiting each element ofx
exactly once. So things like "terms in a syntax, seen as containing variables" can beTraversable
.You can always use
traverse
to do operations on all elements. We getfmap
by takingpure = id
and<*>
to be ordinary application.where
implements simultaneous renaming.
Meanwhile, the
Foldable
instancetakes
pure
to give the neutral element of some monoid and<*>
to the combining operation, so we get reduce-like operations. E.g.,gives the list of variables occurring in a term. That is we can always obtain the sequence of elements from
Traversable
data, but the data might have structure other than those elements.Term
s have structure other than variables (theirVal
s andAdd
s), and it's not so clear what "cons" means for syntax trees.So, while more structures than sequences are
Traversable
, theTraversable
interface offers you fewer sequence-like operations. The point ofTraversable
is to generalize map-like and reduce-like operations, not to capture list-ness.