Maurí­cio | 27 Aug 20:20
Favicon

Haskell symbol ~

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
Favicon

Re: Haskell symbol ~

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 <at> kf8nh.com
system administrator [openafs,heimdal,too many hats] allbery <at> ece.cmu.edu
electrical and computer engineering, carnegie mellon university    KF8NH
C.M.Brown | 27 Aug 21:14
Favicon

Re: Haskell symbol ~

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
(Continue reading)

Jonathan Cast | 27 Aug 21:14
Favicon

Re: Haskell symbol ~

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
C.M.Brown | 27 Aug 21:51
Favicon

Re: Haskell symbol ~

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.

(Continue reading)

Neil Mitchell | 27 Aug 20:56

Re: Haskell symbol ~

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
Ryan Ingram | 27 Aug 21:12

Re: Haskell symbol ~

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 <ndmitchell <at> gmail.com> wrote:
> 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)
(Continue reading)

Maurí­cio | 28 Aug 14:15
Favicon

Re: Haskell symbol ~

 >> 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
Neil Mitchell | 28 Aug 14:22

Re: Re: Haskell symbol ~

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
David House | 28 Aug 15:49

Re: Re: Haskell symbol ~

2008/8/28 Maurí­cio <briqueabraque <at> yahoo.com>:
> 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
Benja Fallenstein | 27 Aug 21:11

Re: Haskell symbol ~

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 <briqueabraque <at> yahoo.com> 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?

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

Gmane