Haskell - 我自己的zip3功能

时间:2018-01-04 19:18:17

标签: list haskell zip tuples

有没有更好的方法来重新创建此功能?它汇编得很好。

这就是我所拥有的:

zip3' :: [a] -> [b] -> [c] -> [(a,b,c)]
zip3' [] _ _ = []
zip3' _ [] _ = []
zip3' _ _ [] = []
zip3' (a:as) (b:bs) (c:cs) = (a,b,c) : zip3' as bs cs

我只是想知道是否有更好的方法来总结这个:

zip3' [] _ _ = []
zip3' _ [] _ = []
zip3' _ _ [] = []

2 个答案:

答案 0 :(得分:15)

工作正常。如果你想缩短程序,你可以写:

zip3' :: [a] -> [b] -> [c] -> [(a,b,c)]
zip3' (a:as) (b:bs) (c:cs) = (a,b,c) : zip3' as bs cs
zip3' _      _      _ = []

如果三个列表中至少有一个不是(_:_)[]),则第一行只会触发。但这有时被视为反模式,因为在一个非常不同的事件中,一个构造函数添加到列表数据类型,这可能最终得到一个空列表(而在这种情况下,我们可能最好得到一个错误)。我同意对于列表来说这几乎是不可能的:许多图书馆和程序将不再有效。但一般来说,例如设计数据类型并随后改变主意并添加额外的构造函数并不罕见。

如果我们检查zip3 :: [a] -> [b] -> [c] -> [(a,b,c)]的源代码,那么我们会看到它以[source]的方式实现:

zip3 :: [a] -> [b] -> [c] -> [(a,b,c)]
-- Specification
-- zip3 =  zipWith3 (,,)
zip3 (a:as) (b:bs) (c:cs) = (a,b,c) : zip3 as bs cs
zip3 _      _      _      = []

出于某种原因zip本身是以“问题”样式[source]实现的:

zip :: [a] -> [b] -> [(a,b)]
zip []     _bs    = []
zip _as    []     = []
zip (a:as) (b:bs) = (a,b) : zip as bs

答案 1 :(得分:6)

你的方法没有任何本质上的错误,但是你可以将前三个案例最终归结为一个全能。

zip3' :: [a] -> [b] -> [c] -> [(a,b,c)]
zip3' (a:as) (b:bs) (c:cs) = (a,b,c) : zip3' as bs cs
zip3' _ _ _ = []

事实上,这是how GHC does it