I'm writing a function pad
that takes a list and pads it until it is a certain size. I tried 2 implementations:
pad :: Monoid a => Int -> [a] -> [a]
pad len list = replicate (len - length list) mempty ++ list
and
pad :: Int -> a -> [a] -> [a]
pad len value list = replicate (len - length list) value ++ list
The first one seems to be a logical usage of Monoid
but calling it with lists of integers (or anything that is a Monoid
in multiple ways) is a pain:
(fmap getSum) <$> pad 8 <$> (fmap Sum) <$> [1,2,3]
I don't really mind the extra typing, but it doesn't even seem to convey the meaning very well. How would you implement this function?
I'd probably use your second example, to be honest. Adding a Monoid
constraint just to use mempty
as a "default value" is overkill. It also sends the wrong message to users of this function, who may be confused about what you need mappend
for when you really don't. They would also have to make a newtype
and a Monoid
instance if they wanted to pad with a different value.
Instead, consider changing the order of the arguments so that the value comes first. Then you can just apply it partially whenever you need to pad a lot of lists with the same value. You can also recover the first version with pad mempty
if you need it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With