在Haskell中用填充进行压缩 [英] Zipping with padding in Haskell
问题描述
有几次,我发现自己希望Haskell中的 zip
能够将填充添加到较短的列表中,而不是截断较长的填充。这很容易写。 ( Monoid
在这里适用于我,但您也可以传入要用于填充的元素。)
zipPad ::(Monoid a,Monoid b)=> [a] - > [b] - > [(a,b)]
zipPad xs [] = zip xs(重复空格)
zipPad [] ys = zip(重复空格)ys
zipPad(x:xs)(y: ys)=(x,y):zipPad xs ys
这种方法在尝试定义 zipPad3
。我输入了以下内容,然后意识到它当然不起作用:
zipPad3 ::(Monoid a,Monoid b ,Monoid c)=> [a] - > [b] - > [c] - > [(a,b,c)]
zipPad3 xs [] [] = zip3 xs(repeat mempty)(repeat mempty)
zipPad3 [] ys [] = zip3(repeat mempty)ys(repeat mempty )
zipPad3 [] [] zs = zip3(重复记忆)(重复记忆)zs
zipPad3 xs ys [] = zip3 xs ys(重复记忆)
zipPad3 xs [] zs = zip3 xs(重复mempty)zs
zipPad3 [] ys zs = zip3(重复mempty)ys zs
zipPad3(x:xs)(y:ys)(z:zs)=(x,y,z ):zipPad3 xs ys zs
在这一点上,我欺骗并使用 length 选择最长的列表并填充其他列表。
我忽略了一种更优雅的方式来做到这一点,或者像 zipPad3
已经在某处定义了?
定制 测试片段: : A couple of times I've found myself wanting a This approach gets ugly when trying to define At this point I cheated and just used Am I overlooking a more elegant way to do this, or is something like How about custom Test snippet: Its output:
这篇关于在Haskell中用填充进行压缩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!头像如何和
尾部
函数(命名为 next
和 rest
在下面的例子中)?
pre $ import Data.Monoid
zipPad ::(幺半群a,幺半群b)=> [a] - > [b] - > [(a,b)]
zipPad [] [] = []
zipPad xs ys =(next xs,next ys):zipPad(rest xs)(rest ys)
zipPad3 ::(Monoid a,Monoid b,Monoid c)=> [a] - > [b] - > [c] - > [(a,b,c)]
zipPad3 [] [] [] = []
zipPad3 xs ys zs =(next xs,next ys,next zs):zipPad3(rest xs)(rest ys)(rest zs)
next ::(Monoid a)=> [a] - > a
next [] = mempty
next xs = head xs
rest ::(Monoid a)=> [a] - > [a]
rest [] = []
rest xs = tail xs
instance Monoid Int其中
mempty = 0
mappend =(+)
main = do
print $ zipPad [1,2,3,4 :: Int] [1,2 :: Int]
print $ zipPad3 [1,2,3, 4 :: Int] [9 :: Int] [1,2 :: Int]
[(1,1),(2,2),(3,0),(4,0)]
pre>
[(1,9,1),(2,0,2),(3,0,0),(4,0,0)]
zip
in Haskell that adds padding to the shorter list instead of truncating the longer one. This is easy enough to write. (Monoid
works for me here, but you could also just pass in the elements that you want to use for padding.)zipPad :: (Monoid a, Monoid b) => [a] -> [b] -> [(a, b)]
zipPad xs [] = zip xs (repeat mempty)
zipPad [] ys = zip (repeat mempty) ys
zipPad (x:xs) (y:ys) = (x, y) : zipPad xs ys
zipPad3
. I typed up the following and then realized that of course it doesn't work:zipPad3 :: (Monoid a, Monoid b, Monoid c) => [a] -> [b] -> [c] -> [(a, b, c)]
zipPad3 xs [] [] = zip3 xs (repeat mempty) (repeat mempty)
zipPad3 [] ys [] = zip3 (repeat mempty) ys (repeat mempty)
zipPad3 [] [] zs = zip3 (repeat mempty) (repeat mempty) zs
zipPad3 xs ys [] = zip3 xs ys (repeat mempty)
zipPad3 xs [] zs = zip3 xs (repeat mempty) zs
zipPad3 [] ys zs = zip3 (repeat mempty) ys zs
zipPad3 (x:xs) (y:ys) (z:zs) = (x, y, z) : zipPad3 xs ys zs
length
to pick the longest list and pad the others.zipPad3
already defined somewhere?head
and tail
functions (named next
and rest
in my example below)?import Data.Monoid
zipPad :: (Monoid a, Monoid b) => [a] -> [b] -> [(a,b)]
zipPad [] [] = []
zipPad xs ys = (next xs, next ys) : zipPad (rest xs) (rest ys)
zipPad3 :: (Monoid a, Monoid b, Monoid c) => [a] -> [b] -> [c] -> [(a,b,c)]
zipPad3 [] [] [] = []
zipPad3 xs ys zs = (next xs, next ys, next zs) : zipPad3 (rest xs) (rest ys) (rest zs)
next :: (Monoid a) => [a] -> a
next [] = mempty
next xs = head xs
rest :: (Monoid a) => [a] -> [a]
rest [] = []
rest xs = tail xs
instance Monoid Int where
mempty = 0
mappend = (+)
main = do
print $ zipPad [1,2,3,4 :: Int] [1,2 :: Int]
print $ zipPad3 [1,2,3,4 :: Int] [9 :: Int] [1,2 :: Int]
[(1,1),(2,2),(3,0),(4,0)]
[(1,9,1),(2,0,2),(3,0,0),(4,0,0)]