Jonas Holmerin wrote:
> 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.
Hmm... indeed. I wonder if there's any reason why zipWith can't just be fully lazy
so that we don't need to twiddle with transpose. I.e., define it as:
zipWith :: (a->b->c) -> [a]->[b]->[c]
zipWith z ~(a:as) ~(b:bs) = z a b : zipWith z as bs
zipWith _ _ _ = []
Perhaps this is an oft visited topic.
--Jeff