
Wed, 29 Aug 2001 12:06:37 +0300, Cagdas Ozgenc
What is the use of ~ symbol in Haskell? For example in prelude function unzip
unzip = foldr (\(a,b) ~(as,bs) -> (a:as, b:bs)) ([], [])
When a lambda abstraction is applied to arguments, objects passed as arguments are matched against patterns in the lambda. The pattern (a,b) causes evaluation of the top-level constructor of the matched value (the constructor must be (,) because of the type) and binds a and b to arguments of the constructor. Matching against the pattern ~(as,bs) succeeds without evaluation of the value. Names as and bs are bound to expressions which cause evaluation of the top-level constructor of the matched value and select appropriate components. So with \(a,b) the constructor is evaluated when the lambda is applied, before evaluation of its body. With \ ~(as,bs) it's evaluated when as or bs are evaluated inside the body. The effect is that laziness is improved: parts of the result are available before the input is consumed. The first argument of foldr should better be lazy in its second argument, so foldr can return something without waiting for the result of the recursive call on the tail of the list being traversed. With this definition unzip ((foo, bar):whatever) can return (foo:whatever', bar:whatever'') where evaluation of whatever' and whatever'' causes further traversal of whatever. It doesn't wait until 'unzip whatever' returns the pair but it returns an object whose components cause evaluation of 'unzip whatever'. There is no ~ on (a,b). This implies that unzip (spam:eggs) does evaluate spam to obtain a pair before returning anything. It delays only the recursive call of 'unzip eggs'. -- __("< Marcin Kowalczyk * qrczak@knm.org.pl http://qrczak.ids.net.pl/ \__/ ^^ SYGNATURA ZASTÊPCZA QRCZAK

Thanks for the elaborate explanation! Here's an example that may serve to elucidate: The problem, of course, is when unzipping an infinite lists, e.g. the result of zip [1..] [1..] which of course looks like [(1,1), (2,2), ...] defining unzip' as unzip' = foldr (\(a,b) (as,bs) -> (a:as, b:bs)) ([], []) (i.e. without the lazy match on (as,bs)), take 4 $ fst $ unzip' $ zip [1..] [1..] hangs forever, while using the regular, lazy unzip results in the expected [1,2,3,4] -kzm -- If I haven't seen further, it is by standing in the footprints of giants
participants (2)
-
Ketil Malde
-
Marcin 'Qrczak' Kowalczyk