The other day, I tried to transpose an infinite list of finite list:
Simplified example:
transpose (repeat [1..5])
This won't terminate, since transpose is defined as
transpose :: [[a]] -> [[a]]
transpose = foldr
(\xs xss -> zipWith (:) xs (xss ++ repeat []))
[]
The evalutation goes something like this:
foldr (\xs xss -> zipWith (:) xs (xss ++ repeat [])) [] (repeat [1..5]) =>
zipWith (:) ([1..5])
(foldr (\xs xss -> zipWith (:) xs (xss ++ repeat [])) [] (repeat [1..5]))
Which will loop forever since zipWith is strict in its third argument.
Not a big deal, perhaps, but it's unsymmetric, since it's possible
to transpose a finite list of infinite lists. The following definition
of transpose works:
transpose :: [[a]] -> [[a]]
transpose = foldr
(\xs xss -> zipLazier (:) xs (xss ++ repeat []))
[]
where
zipLazier f (x:xs) xss = f x (head xss) : zipLazier f xs (tail xss)
zipLazier _ _ _ = []