= Solution
Use the usual left-to-right <pattern matching> order:
``
zip :: [a] -> [b] -> [(a,b)]
zip [] _ = []
zip _ [] = []
zip (x:xs) (y:ys) = (x,y) : zip xs ys
``
The result stops when either <list> ends, so its length on finite total inputs is the smaller input length. Elements remaining in the longer <list> are discarded.
Strictness is asymmetric. Writing the <bottom value> as $\bot$, \b[`zip` is strict in its first list but not uniformly strict in its second]: `zip undefined ys` is undefined, whereas `zip [] undefined = []`. With a nonempty first <list>, an undefined second <list> does make the result undefined. Neither pair component is forced merely to produce the outer result constructor: `zip [undefined] [undefined]` already has a defined outer cons and pair. This follows from ordered <pattern matching> and <lazy evaluation>, not from the behavior on total <lists> alone.<Haskell 2010 Language Report>[§3.17.2, ordered pattern matching; Chapter 9, zip in the Standard Prelude]{ref}
Back to article page