haskell - 关于 Haskell 中的 ~ 和 @ 运算符的问题

标签 haskell operator-keyword primes sieve

他们具体是做什么的?我知道 @ 的一种可能用法(在模式匹配开始时分配名称),但在 ~.

我在以下代码片段中找到了它们,取自 http://www.haskell.org/haskellwiki/Prime_numbers ,但本文假设您精通 Haskell 语法,并且不会费心解释其深奥的运算符(我感到困惑的部分是 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)

任何关于此处使用的语法的解释(或链接)将不胜感激。

最佳答案

运营商~使比赛变得懒惰。通常模式匹配会评估参数,因为需要检查模式是否失败。如果您在模式前加上 ~ ,直到需要时才进行评估。此功能常用于 “Tying the knot”代码,其中需要引用尚未创建的结构。如果模式在评估时失败,则结果为 undefined .

这是一个例子:

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

g ~(_:_) = True
g []     = False
f []产量 False , 而 g []产生 true,因为第一个模式总是匹配的。 (您实际上会收到此代码的警告)

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

请注意,这些运算符仅在它们应用的级别上使事情变得严格/惰性,而不是递归地。例如:
h ~((x,y):xys) = ...

元组上的模式匹配是严格的,但 cons 模式是惰性的。

关于haskell - 关于 Haskell 中的 ~ 和 @ 运算符的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7506684/

相关文章:

haskell - Codec.Binary.Base64.encode 很慢

c++ - 在 C++ 结构中重载运算符 << 和 >>

c++ - 子类化、赋值运算符和复制构造函数

c++ - 如何将数字的每个数字向右排列一步?

math - 小数的最快素数测试

haskell - 在 Haskell 中处理大文件

haskell - 如何在单子(monad)中使用 Kleisli 箭头?

haskell - 如何获得调用错误的位置?

c++ - STL 流 : forward operator<< calls 的包装类

c - 关于如何使我的算法更快的建议