Lazy pattern match
From HaskellWiki
What does "lazy pattern match" mean and what is the meaning of the tilde in pattern matches?
1 Syntax
These are all lazy pattern matches:
let (a,b) = p
f ~(a,b) = ...
case p of ~(a,b) -> ...
(\ ~(a,b) -> ... )
This seems to be quite arbitrary but this is how it is defined. That is, if you want to match constructors lazily in two levels then you have to write:
let (a, ~(b,c)) = p
f ~(a, ~(b,c)) = ...
case p of ~(a, ~(b,c)) -> ...
(\ ~(a, ~(b,c)) -> ... )
2 Meaning
What is the meaning of a lazy pattern match and why is it required sometimes?
The lazy pattern match on a pair as in
f ~(a,b) = g a b
can be translated to
f p = g (fst p) (snd p)
Generally, a lazy pattern match is translated to calling corresponding record field accessors. The key difference between strict pattern match
f (a,b) = g a b
and lazy pattern match
f ~(a,b) = g a b
import Prelude hiding (splitAt) splitAt :: Int -> [a] -> ([a], [a]) splitAt n xs = if n<=0 then ([], xs) else case xs of [] -> ([], []) y:ys -> case splitAt (n-1) ys of ~(prefix, suffix) -> (y : prefix, suffix)
Now try
Test> splitAt 1000000 $ repeat 'a'
3 Implications
The lazy pattern match has some consequences. First of all a lazy pattern matches immediately always. Remember,
f ~(x:xs) = x:xs
is translated to
f ys = head ys : tail ys
f :: [a] -> [a] f [] = [] f ~(x:xs) = x:xs
is fine but stupid, because the first match already requires the decision whether the list is empty or not. But the reversed order
f :: [a] -> [a] f ~(x:xs) = x:xs f [] = []
