Haskell - 我自己的zip3功能

Fil*_*ega 9 zip haskell tuples list

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

这就是我所拥有的:

zip3' :: [a] -> [b] -> [c] -> [(a,b,c)]
zip3' [] _ _ = []
zip3' _ [] _ = []
zip3' _ _ [] = []
zip3' (a:as) (b:bs) (c:cs) = (a,b,c) : zip3' as bs cs
Run Code Online (Sandbox Code Playgroud)

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

zip3' [] _ _ = []
zip3' _ [] _ = []
zip3' _ _ [] = []
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 15

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

zip3' :: [a] -> [b] -> [c] -> [(a,b,c)]
zip3' (a:as) (b:bs) (c:cs) = (a,b,c) : zip3' as bs cs
zip3' _      _      _ = []
Run Code Online (Sandbox Code Playgroud)

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

如果我们检查源代码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 _      _      _      = []
Run Code Online (Sandbox Code Playgroud)

出于某种原因,zip它本身是以"问题"风格[来源]实现的:

zip :: [a] -> [b] -> [(a,b)]
zip []     _bs    = []
zip _as    []     = []
zip (a:as) (b:bs) = (a,b) : zip as bs
Run Code Online (Sandbox Code Playgroud)

  • 打败我说同样的事情,但你更详细.打的好. (2认同)
  • 看起来像[docs](http://hackage.haskell.org/package/base-4.10.1.0/docs/Prelude.html#v:zip)指定`zip`是对的,但是`zip3`是没有这样的限制.这可以解释实现中的差异,并且它也提出了一个有趣的观点,即在我之前没有考虑过的OP风格中执行代码的好处. (2认同)
  • @SilvioMayolo:据我所知,模式匹配是从左到右完成的.所以它也会首先将第一个参数与`(a:as)`匹配,所以afaik,语义没有区别.无论如何,我们都提到Prelude的源代码很有趣:) (2认同)
  • 看来,两者是等价的.https://gist.github.com/Mercerenies/b9174f7ff0bf8637df055b6462ffe917 (2认同)

Sil*_*olo 6

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

zip3' :: [a] -> [b] -> [c] -> [(a,b,c)]
zip3' (a:as) (b:bs) (c:cs) = (a,b,c) : zip3' as bs cs
zip3' _ _ _ = []
Run Code Online (Sandbox Code Playgroud)

事实上,GHC就是这样做的.