Names for small functions: just say no... Re: Data.List.join

kahl at kahl at
Fri Nov 10 12:34:28 EST 2006

Jón Fairbairn wrote:

 > Largely pointless rumination follows.
 > One of the properties is the type; I can immediately think
 > of three types that the "intuitive" function might have:
 > intersperse :: a -> [a] -> [a]
 > inter_concat :: [a] -> [a] -> [a] -- not the best name?
 > intercalate :: [a] -> [[a]] -> [a]
 > from that I should prefer intersperse on the grounds that it
 > has a simpler type, but when I tried writing each in terms
 > of the other, I found that the definitions of intersperse
 > and intercalate in terms of inter_concat were both nice and
 > obvious. Defining inter_concat in terms of intersperse is a
 > bit messy, and inter_concat in terms of intercalate only
 > slightly less so, which bend me towards the belief that
 > inter_concat is the most primitive!

With inter_concat, I have to guess what it might mean;
the other two are clear to me.

One major use of intercalate is of course for show functions;
since I still tend to define my show instances
via showsPrec rather than show,
I found the following function useful --- the type is rather general,
but the (unreflected) name gives away its normal use:

sepShowsList :: (s -> s) -> (a -> s -> s) -> [a] -> s -> s
sepShowsList sep shows [] = id
sepShowsList sep shows [x] = shows x
sepShowsList sep shows (x:xs) = shows x . sep . sepShowsList sep shows xs

The obvious generalisation is to monoids
(ignoring the fact that sepShowsList also has a map built in),
and we see that the underlying algebraic effect is
to use |mSep| to produce a semigroup from a monoid element:

type SemiGroup s = s -> s -> s            -- must be associative

mSep :: Monoid m => m -> SemiGroup m
mSep x y z = y `mappend` x `mappend` z

mSepConcat :: Monoid m => m -> [m] -> m
mSepConcat = foldr1 . mSep

Note that the last is a point-free definition ;-)

 > The only conclusion I can really draw from this is that the
 > argument that wins for me is still: intersperse got there
 > first, it may not be ideal, but the grounds for adding
 > another are too weak.

The one I have been defining again and again is intercalate,
mostly as:

sepConcat :: [a] -> [[a]] -> [a]

If it is not provided by the library, I will define it again,
and many others will probably do the same,
only perhaps with different names ...


More information about the Libraries mailing list