haskell - `where` block 中的全局 CAF - Haskell

标签 haskell caching functional-programming lazy-evaluation

我将实现一个函数,它接受一个Integer并输出一个惰性的、无限的coprime Integer列表。

coprime 2 = [1,3..]
coprime 3 = [1,2,4,5,7,8,....]

我预计这些列表将被多次访问,因此我希望将它们的值存储为 CAF。 (如果我错误地使用了这个术语,请原谅我)好的,没关系,因为这将由编译器自动完成(我认为)。但是,如何保证不同的输入具有相同的输出呢?例如:

coprime 2 = [1,3..]
coprime 4 = [1,3..]

如何确保这两种模式调用相同的 CAF,以便不必重新计算结果?


我的第一个想法是尝试实现coprime,以便coprime 2coprime 4实际上调用具有相同参数的本地函数。一个最小的例子:

coprime n
  | n == 4    = realcoprime 2
  | otherwise = realcoprime n
    where
      realcoprime n = .....

但是对 coprime 的所有调用都共享与 realcoprime 关联的相同 CAF 值吗?如果是这样,它们是否会因为不在全局范围内而被过早地垃圾收集?

最佳答案

一般函数无法被内存( at least in general they can't )。如果您希望 Haskell 记住函数,这意味着它必须在运行时保存已看到的输入及其相应输出的字典,但函数调用涉及在该字典中查找!

但是,有一些库提供此功能:memoizedata-memocombinators例如。例如,使用后者,我可以用以下命令记住您的示例

import qualified Data.MemoCombinators as Memo

coprime :: Integer -> [Integer]
coprime n = Memo.integral coprime'
  where
    coprime' = -- your definition here - can even use `coprime`

那么关于你的第二个问题,现在适合创建第二个函数,最终调用第一个函数。

关于haskell - `where` block 中的全局 CAF - Haskell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39583995/

相关文章:

haskell - 有没有办法在 Haskell 中模拟线性类型?

javascript - 在浏览器上缓存图像

scala - 在 Scala 中使用 FoldRight 的 FoldLeft

javascript - 在 Ramda 中有条件地 promise

list - Haskell 无限递归

haskell - 是否可以有一个带有多个参数的 optparse-applicative 选项?

haskell - 获取函数的地址(不与 C 接口(interface))

PHP 删除所有包含给定字符串的文件

caching - 缓存集和标签

haskell - 在 lambda 演算中找到解决方案后,将其转换为代码有多容易?