有没有更好的方法来重新创建此功能?它汇编得很好。
这就是我所拥有的:
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' _ _ [] = []
答案 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。