
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 ... Wolfram