我正在编写一个函数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]
我真的不介意额外输入,但它似乎甚至没有很好地表达意思。你会如何实现这个功能?
答案 0 :(得分:11)
说实话,我可能会使用你的第二个例子。添加Monoid
约束仅使用mempty
作为“默认值”是过度的。它还向该功能的用户发送错误的消息,他们可能会对您需要mappend
时的内容感到困惑。如果他们想要使用不同的值填充,他们还必须制作newtype
和Monoid
个实例。
相反,请考虑更改参数的顺序,以便值首先出现。然后,只要需要填充大量具有相同值的列表,就可以部分应用它。如果需要,您还可以使用pad mempty
恢复第一个版本。