Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Question about the ~ and @ operators in Haskell

What exactly do they do? I know one possible use of @ (assigning a name at the start of a pattern match), but haven't been able to find anything on ~.

I found them in the following code snippet, taken from http://www.haskell.org/haskellwiki/Prime_numbers, but the article assumes that you're fluent in Haskell syntax and doesn't bother explaining its esoteric operators (the part I'm confused about is the start of the declaration for sieve):

primesPT () = 2 : primes'
  where 
    primes' = sieve [3,5..] primes' 9
    sieve (p:xs) ps@ ~(_:t) q
       | p < q   = p : sieve xs ps q
       | True    =     sieve [x | x<-xs, rem x p /= 0] t (head t^2)

Any explanation (or link to one) about the syntax used here would be greatly appreciated.

like image 970
damien Avatar asked Sep 21 '11 21:09

damien


People also ask

Where can I ask Haskell questions?

Q. What are the best places to ask beginner questions? A. The beginners mailing list, the haskell-cafe mailing list, or the #haskell irc channel.

What does the operator do in Haskell?

Haskell provides special syntax to support infix notation. An operator is a function that can be applied using infix syntax (Section 3.4), or partially applied using a section (Section 3.5).

What is <> called in Haskell?

It's an alias for mappend , from the Data. Monoid module.


1 Answers

The operator ~ makes a match lazy. Usually a pattern-match evaluates the argument, as there is a need to check whether the pattern fails. If you prefix a pattern with ~, there is no evaluation until it is needed. This functionality is often used in “Tying the knot” code, where one needs to refer to structures that are not yet created. If the pattern fails upon evaulation, the result is undefined.

Here is an example:

f (_:_) = True
f []    = False

g ~(_:_) = True
g []     = False

f [] yields False, while g [] yields true, because the first pattern always matches. (You actually get a warning for this code)

That said, you can see ~ as the opposite of !, which forces the evaluation of an argument even if it's unneeded.

Note that these operators only make things strict/lazy at the level they are applied at, not recursively. For example:

h ~((x,y):xys) = ...

The pattern match on the tuple is strict, but the cons pattern is lazy.

like image 187
fuz Avatar answered Oct 19 '22 21:10

fuz