简体   繁体   English

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

[英]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 ): 我在下面的代码片段中找到了它们,取自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)

Any explanation (or link to one) about the syntax used here would be greatly appreciated. 关于这里使用的语法的任何解释(或链接到一个)将不胜感激。

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 . 如果模式在评估时失败,则结果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. f []得到False ,而g []得到true,因为第一个模式总是匹配。 (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. 元组上的模式匹配是严格的,但缺点模式是懒惰的。

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 [] . 基本上,即使输入是空列表[]~(_:t)也将始终匹配。 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM