5

我正在编写一个函数pad,它接受一个列表并将其填充到一定大小。我尝试了 2 个实现:

pad :: Monoid a => Int -> [a] -> [a]
pad len list = replicate (len - length list) mempty ++ list

pad :: Int -> a ->  [a] -> [a]
pad len value list = replicate (len - length list) value ++ list

第一个似乎是合乎逻辑的用法,但用整数列表(或以多种方式Monoid表示的任何内容)调用它是一种痛苦:Monoid

(fmap getSum) <$> pad 8 <$> (fmap Sum) <$> [1,2,3]

我真的不介意额外的打字,但它似乎甚至不能很好地传达意思。你将如何实现这个功能?

4

1 回答 1

11

老实说,我可能会使用你的第二个例子。添加一个Monoid仅用mempty作“默认值”的约束是矫枉过正的。mappend它还会向此功能的用户发送错误信息,当您真正不需要时,他们可能会对您需要什么感到困惑。如果他们想用不同的值填充,他们还必须创建一个newtype和一个实例。Monoid

相反,请考虑更改参数的顺序,以使值排在第一位。然后,只要您需要填充许多具有相同值的列表,您就可以部分应用它。pad mempty如果需要,您还可以恢复第一个版本。

于 2013-05-29T22:16:17.987 回答