Haskell - 包装和展开newtype包装器 - 有更简单的方法吗?

时间:2013-05-29 22:06:57

标签: haskell monoids

我正在编写一个函数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]

我真的不介意额外输入,但它似乎甚至没有很好地表达意思。你会如何实现这个功能?

1 个答案:

答案 0 :(得分:11)

说实话,我可能会使用你的第二个例子。添加Monoid约束仅使用mempty作为“默认值”是过度的。它还向该功能的用户发送错误的消息,他们可能会对您需要mappend时的内容感到困惑。如果他们想要使用不同的值填充,他们还必须制作newtypeMonoid个实例。

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