Pregunta

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.

¿Fue útil?

Solución

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.

Otros consejos

It's a lazy pattern match (also known as irrefutable pattern match which I think is the better name).

Essentially, ~(_:t) will always match, even if the input is the empty list []. Of course, this is dangerous if you don't know what you're doing:

Prelude> let f ~(_:t) = t in f []
*** Exception: <interactive>:1:4-15: Irrefutable pattern failed for pattern (_ : t)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top