Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell - wrapping and unwrapping newtype wrappers - is there an easier way?

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?

like image 492
Drew Avatar asked May 29 '13 22:05

Drew


1 Answers

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.

like image 168
hammar Avatar answered Nov 15 '22 08:11

hammar