关于Haskell中〜和@运算符的问题

dam*_*ien 14 primes haskell sieve operator-keyword

他们究竟做了什么?我知道可能使用@(在模式匹配开始时指定一个名字),但是在〜上找不到任何东西.

我在下面的代码片段中找到了它们,取自http://www.haskell.org/haskellwiki/Prime_numbers,但是本文假设您能够熟练使用Haskell语法并且不打算解释其深奥的操作符(第一部分) '混淆是筛子宣言的开始):

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)
Run Code Online (Sandbox Code Playgroud)

关于这里使用的语法的任何解释(或链接到一个)将不胜感激.

fuz*_*fuz 11

操作员~使比赛变得懒散.通常,模式匹配会评估参数,因为需要检查模式是否失败.如果使用模式前缀~,则在需要之前不会进行评估.此功能通常用于"绑结"代码,其中需要引用尚未创建的结构.如果模式在评估时失败,则结果为undefined.

这是一个例子:

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

g ~(_:_) = True
g []     = False
Run Code Online (Sandbox Code Playgroud)

f []产量False,而g []产量为真,因为第一种模式总是匹配.(您实际上会收到此代码的警告)

也就是说,您可以看到~相反的情况!,即使不需要,也会强制对参数进行评估.

请注意,这些运算符仅在应用它们的级别上进行严格/延迟,而不是递归.例如:

h ~((x,y):xys) = ...
Run Code Online (Sandbox Code Playgroud)

元组上的模式匹配是严格的,但缺点模式是懒惰的.


Tho*_*mas 9

这是一个懒惰的模式匹配(也称为无可辩驳的模式匹配,我认为是更好的名称).

基本上,~(_:t)即使输入是空列表,也将始终匹配[].当然,如果您不知道自己在做什么,这很危险:

Prelude> let f ~(_:t) = t in f []
*** Exception: <interactive>:1:4-15: Irrefutable pattern failed for pattern (_ : t)
Run Code Online (Sandbox Code Playgroud)