
Hi, What does '~' mean in Haskell? I read in haskell.org/haskellwiki/Keywords that “(...) Matching the pattern ~pat against a value always suceeds, and matching will only diverge when one of the variables bound in the pattern is used.” Isn't that true for any variable, due to lazyness? At the same place, I found that example, but wasn't wise enough to figure out what it does: (f *** g) ~(x,y) = (f x, g y) Can you help me understand it? Thanks, Maurício

On 2008 Aug 27, at 14:23, Maurí cio wrote:
What does '~' mean in Haskell? I read in haskell.org/haskellwiki/Keywords that “(...) Matching the pattern ~pat against a value always suceeds, and matching will only diverge when one of the variables bound in the pattern is used.” Isn't that true for any variable, due to lazyness?
Only in let-patterns; others, including case expressions and top level definitions, are strict (which is in fact the normal way to force a value). -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

Hi, I may be wrong here, but I don't belive it's just let-patterns that have this property. I.e. what's the difference between... (Just x) = _|_ f = x vs. f = let (Just x) = _|_ in x vs. f = x where (Just x) = _|_ I believe Haskell uses Normal Order Reduction in all these cases. Why is it just let-patterns? Can you give an example? Thanks, Chris. On Wed, 27 Aug 2008, Brandon S. Allbery KF8NH wrote:
On 2008 Aug 27, at 14:23, Maurí cio wrote:
What does '~' mean in Haskell? I read in haskell.org/haskellwiki/Keywords that “(...) Matching the pattern ~pat against a value always suceeds, and matching will only diverge when one of the variables bound in the pattern is used.” Isn't that true for any variable, due to lazyness?
Only in let-patterns; others, including case expressions and top level definitions, are strict (which is in fact the normal way to force a value).

On Wed, 2008-08-27 at 20:14 +0100, C.M.Brown wrote:
Hi,
I may be wrong here, but I don't belive it's just let-patterns that have this property. I.e. what's the difference between...
(Just x) = _|_
f = x
vs.
f = let (Just x) = _|_ in x
vs.
f = x where (Just x) = _|_
I believe Haskell uses Normal Order Reduction in all these cases. Why is it just let-patterns? Can you give an example?
Those are all syntax sugar for let patterns. jcc

I personally think it's bad to start using "let-patterns" as a synonym for general pattern bindings when explaining these concepts. It may be true that it's all transformed into the same thing at core level, but a let expression binds a definition at the expression level, rather than at the equation level; it becomes difficult when we have guards, for example: f pat1 | pat1 == x = x | pat2 == e2 = x where Just x = ... f pat2 = ... g pat1 | pat1 == let Just x = ... in x = let Just x = ... in x | pat2 == e2 = let Just x = ... in x g pat2 = ... In theory x is lazy in f, but computed twice in g. The only way to make the two the same is to introduce a case expression within a let binding -- but then you have to start thinking about things like uncurrying g if it has multiple parameters and its implications with partial applications. Most decent compiler implementations would make a closue for x anyway (if it's a big enough expression to compute), but I think it's certainly worth making the distinction, otherwise new people are going to start thinking they need to define everything using "let" clauses rather than "wheres" for laziness. Regards, Chris. On Wed, 27 Aug 2008, Jonathan Cast wrote:
On Wed, 2008-08-27 at 20:14 +0100, C.M.Brown wrote:
Hi,
I may be wrong here, but I don't belive it's just let-patterns that have this property. I.e. what's the difference between...
(Just x) = _|_
f = x
vs.
f = let (Just x) = _|_ in x
vs.
f = x where (Just x) = _|_
I believe Haskell uses Normal Order Reduction in all these cases. Why is it just let-patterns? Can you give an example?
Those are all syntax sugar for let patterns.
jcc

Hi
At the same place, I found that example, but wasn't wise enough to figure out what it does:
(f *** g) ~(x,y) = (f x, g y)
Can you help me understand it?
It means exactly the same as: (f *** g) xy = (f (fst xy), g (snd xy)) i.e. if you call (f *** g) undefined, you will get (f undefined, g undefined). If the pattern was strict (i.e. no ~) you would get undefined. Please update the keyword wiki so it makes sense to you, after you have got your head round it. Thanks Neil

Here is another example:
f1 n ~(x:xs) = (n, x) f2 n (x:xs) = (n,x)
f1 5 [] = (5, error "irrefutable pattern match failure")
f2 5 [] = error "pattern match failure"
In particular:
fst (f1 5 []) = 5
fst (f2 5 []) = error "pattern match failure"
The "~" delays the pattern match until evaluation of the variables
inside the pattern is demanded. If the variable is never demanded,
the pattern match doesn't happen.
It's especially useful for single-constructor datatypes (like pairs)
if you want the code to be more lazy.
-- ryan
On Wed, Aug 27, 2008 at 11:56 AM, Neil Mitchell
Hi
At the same place, I found that example, but wasn't wise enough to figure out what it does:
(f *** g) ~(x,y) = (f x, g y)
Can you help me understand it?
It means exactly the same as:
(f *** g) xy = (f (fst xy), g (snd xy))
i.e. if you call (f *** g) undefined, you will get (f undefined, g undefined). If the pattern was strict (i.e. no ~) you would get undefined.
Please update the keyword wiki so it makes sense to you, after you have got your head round it.
Thanks
Neil _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

At the same place, I found that example, but wasn't wise enough to figure out what it does:
(f *** g) ~(x,y) = (f x, g y)
(...)
(...) Please update the keyword wiki so it makes sense to you, after you have got your head round it.
After the explanations, I think I got it, and just updated the wiki. If you guys have some time please check it for style and errors. I also got a few wrong default links (I just created +++ inside <haskell></haskell> and it links to something that doesn't exist). Here it is: http://haskell.org/haskellwiki/Keywords#.7E Thanks, Maurício

Hi
After the explanations, I think I got it, and just updated the wiki.
Many thanks. That wiki page is automatically pulled into the Hoogle search engine when I update it, so having good definitions for every new keyword is a real bonus :-)
I also got a few wrong default links (I just created +++ inside <haskell></haskell> and it links to something that doesn't exist).
I wouldn't worry about that, I think its a bug in the wiki software. Does anyone know who our wiki software guru is? Perhaps wiki links should point at Hoogle, rather than using its own (obviously imperfect) database? Thanks Neil

2008/8/28 Maurício
After the explanations, I think I got it, and just updated the wiki.
Glad you've understood it. Seems I arrived a little late at this thread, but there is also: http://en.wikibooks.org/wiki/Haskell/Laziness#Lazy_pattern_matching In addition, the first three chapters of that page might be worth reading if you're a little unclear about laziness etc. in general. -- -David

Hi Maurício,
I've got one thing to add to the replies so far:
On Wed, Aug 27, 2008 at 8:23 PM, Maurício
What does '~' mean in Haskell? I read in haskell.org/haskellwiki/Keywords that "(...) Matching the pattern ~pat against a value always suceeds, and matching will only diverge when one of the variables bound in the pattern is used." Isn't that true for any variable, due to lazyness?
To any variable, yes. But you don't apply it to a variable, you apply it to a constructor pattern: not ~xs but ~(x:xs). Best, - Benja
participants (8)
-
Benja Fallenstein
-
Brandon S. Allbery KF8NH
-
C.M.Brown
-
David House
-
Jonathan Cast
-
Maurício
-
Neil Mitchell
-
Ryan Ingram