2013-05-29 39 views
4

我正在寫一個函數pad,它需要一個列表並填充它,直到它達到一定的大小。我試過2個實現:Haskell - 包裝和展開新包裝 - 有沒有更簡單的方法?

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

我會用'pad :: Int - > a - > [a] - > [a]'。有時候,人們想要填補不同的價值。 –

+4

爲好奇鍛鍊。考慮'data Paddy a = [a]:...:a'並配備'Paddy'以壓縮'Applicative'結構,它將':...:'左邊的值配對,但是通過填充長度不匹配在':...:'後給出的值較短的列表。 – pigworker

回答

10

我可能會用你的第二個例子,說實話。僅僅使用mempty作爲「默認值」添加Monoid約束是矯枉過正的。它也向這個功能的用戶發送了錯誤的信息,當你真的不需要時,他們可能會對你需要的mappend感到困惑。如果他們想要填充不同的值,他們還必須製作newtypeMonoid實例。

相反,請考慮更改參數的順序,以使值首先出現。然後,只要需要填充許多具有相同值的列表,就可以部分應用它。如果您需要,也可以使用pad mempty恢復第一個版本。

+1

我喜歡部分應用建議。我想我會用它。 – Drew