如此实现zipWithPadding存在哪些局限?(Haskell自定义zipWith替代方案)
不等长列表的Zip操作泛化实现问题
处理不等长列表的zip操作时,不想让结果被最短列表截断(典型场景是对整数列表进行加减乘运算),我想知道如何设置类型变量来实现更泛化的定义,同时不确定是否需要针对每个场景定制实现,还是可以通过高阶函数复用逻辑。
初始实现代码如下:
zipWithPadding :: a -> (a -> a -> a) -> [a] -> [a] -> [a] zipWithPadding n f = go n f where go n f [] a = [f n x | x <- a] go n f a [] = [f n x | x <- a] go n f (x:xs) (y:ys) = f x y : go n f xs ys
感谢评论区Chris的帮助,将实现修改为更泛化的版本:
zipPadWith :: a -> b -> (a -> b -> c) -> [a] -> [b] -> [c] zipPadWith n m f = go n m f where go n _ f [] a = [f n x | x <- a] go _ m f a [] = [f x m | x <- a] go n m f (x:xs) (y:ys) = f x y : go n m f xs ys
基于这个泛化版本,我实现了transposeWith函数:
transposeWith :: a -> [[a]] -> [[a]] transposeWith n [] = [] transposeWith n (ms:mss) = zipPadWith n [n | _ <- mss] (:) ms (transposeWith n mss)
该函数可以在不截断内容的情况下转置列表,还能通过自定义填充元素让结果呈矩形;不过它无法处理任意数量的子列表,但支持处理无限子列表。
内容的提问来源于stack exchange,提问作者Marco_O
相关产品推荐
相关产品推荐

