Names for small functions: just say no... Re: Data.List.join
kahl at cas.mcmaster.ca
kahl at cas.mcmaster.ca
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 ...
Wolfram
More information about the Libraries
mailing list