~ symbol

Marcin 'Qrczak' Kowalczyk qrczak@knm.org.pl
29 Aug 2001 10:57:27 GMT

Wed, 29 Aug 2001 12:06:37 +0300, Cagdas Ozgenc <co19@cornell.edu> pisze:

> 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