Haskell-这个素性测试中的lambda是什么意思?它是如何工作的?
从中,有以下代码:Haskell-这个素性测试中的lambda是什么意思?它是如何工作的?,haskell,primes,lambda,primality-test,Haskell,Primes,Lambda,Primality Test,从中,有以下代码: isPrime n = n > 1 && foldr (\p r -> p*p > n || ((n `rem` p) /= 0 && r)) True primes 其中素数是素数的列表(可能是无限的) 两个问题: 如何读取传递给foldr函数的lambda 既然foldr是从右边开始的,那么当传递给它一个无限素数列表时,为什么这个函数可以工作呢?我猜lambda里有短路 lambda部分看起来像是被翻译成pyth
isPrime n = n > 1 &&
foldr (\p r -> p*p > n || ((n `rem` p) /= 0 && r)) True primes
其中素数是素数的列表(可能是无限的)
两个问题:
foldr
函数的lambdafoldr
是从右边开始的,那么当传递给它一个无限素数列表时,为什么这个函数可以工作呢?我猜lambda里有短路lambda部分看起来像是被翻译成pythonish伪代码: 至于
foldr
部分,这确实很棘手<然后,列表(r
)的code>foldr)将该功能应用于头部和r
。因此,必须有一个点,在这个点上,可以不进一步计算尾部
当头部至少是
sqrt(n)
时就会发生这种情况,这意味着:如果有除数,你可以在之前找到它,但现在返回True,不计算尾部。延迟求值意味着布尔短路逻辑停止正在求值的函数链,即使逻辑在函数内部
作为一个简单的示例,对于任何可折叠数据类型,您都可以编写如下的null
函数:
null t = foldr (\x b -> False && b) True t
isPrime n = n > 1 &&
foldr f True primes
where
f p r = p*p > n || ((n `rem` p) /= 0 && r)
此函数永远不会被多次调用,因为对于具有多个元素的实例,它将对其求值
False && *thunk* foldr...
短路布尔值和意味着thunk永远不会被计算,因此这将很好地用于无限结构。这就是为什么不应该实现null
作为检查size==0
这在严格的语言中不起作用;foldr的每个迭代都将依次进行评估并传递给下一个迭代
至于lambda
isPrime n = n > 1 &&
foldr (\p r -> p*p > n || ((n `rem` p) /= 0 && r)) True primes
可以这样写:
null t = foldr (\x b -> False && b) True t
isPrime n = n > 1 &&
foldr f True primes
where
f p r = p*p > n || ((n `rem` p) /= 0 && r)
希望有帮助
编辑:如果不清楚,该函数中的短路布尔值或
|
的工作方式与上面的简单示例相同。折叠可能很容易从视觉上把握:
foldr g z [a,b,c...,x] === g a (g b (g c (g ... (g x z) ... )))
因此,如果gpr
不使用其第二个参数,它将不会强制任何进一步的列表访问。正如您所说,由于|
(“逻辑or”)的短路行为
和foldlgz[a,b,c…,x]==(g…(g(gza)b)c)…x)
要阅读函数,首先我们注意到折叠应用于素数列表,[2,3,5,7,11,13,17..]
。所以可以理解为
isPrime n=n>1&&
foldr(\pr->p*p>n | |((n`rem`p)/=0&&r))真素数
===
iPrime n=n>1&&
(2*2>n | |(rem n2/=0&&
(3*3>n | |(rem n3/=0&&
(5*5>n||(rem n5/=0&&
--当p*p>n时,膨胀停止
--因为(真| | r)==真
......................... &&
(对)()("""))
在
foldr
的组合函数中,第二个参数表示折叠列表其余部分的“结果”r
是一个具有暗示意义的名称。你会问,“如何翻译lambda?”。我问,“翻译成什么?”thx,为澄清而编辑+对于链接,我还没有完全理解折叠的工作原理,如果p不除以n,我更喜欢,返回r
关于foldr
:Haskell是懒惰的,因此实际上在第一次调用合并函数之前不会计算r
。只有在请求r
的值时才会尝试计算r
的值。这是对折叠的一个很好的解释,但我认为我接受的答案更好地说明了折叠和lambda在这种情况下是如何工作的。嗯,我开始说这是关于短路布尔逻辑,在LAMBDA的中间有一个大的<代码> <代码>代码SLAP。在你更新之前,根本不清楚你所说的“lambda是如何工作的?”。我接受了这个答案,因为它更清楚地解释了折叠和lamdba在这个函数中是如何工作的。谢谢