有没有办法让 "preserve" 结果变成 Haskell?

Is there a way to "preserve" results in Haskell?

我是 Haskell 的新手,我知道它(基本上)是一种纯函数式语言,其优点是函数的结果不会在多次评估中发生变化。鉴于此,我很困惑为什么我不能轻松地标记一个函数,使其记住其第一次评估的结果,并且不必在每次需要其值时再次评估。

Mathematica, for example, there is a simple idiom 中完成此操作:

f[x_]:=f[x]= ...

但在 Haskell 中,我发现的最接近的是 something like

f' = (map f [0 ..] !!)
   where f 0 = ... 
         f n = f' ...

除了不太清楚(并且显然仅限于 Int 参数?)之外,它(似乎)不会在交互式会话中保留结果。

诚然(而且很明显),我不明白这里到底发生了什么;但天真地,Haskel 似乎应该在函数定义级别有一些方法

有什么方法可以在 Haskell 中完成我所缺少的吗?我理解(有点)Haskell 不能将评估存储为 "state",但为什么它不能简单地(实际上)将评估函数重新定义为它们的计算值?


这源于 this question,其中缺少此功能会导致糟糕的性能。

使用合适的库,例如MemoTrie

import Data.MemoTrie

f' = memo f
 where f 0 = ... 
       f n = f' ...

这几乎不亚于 Mathematica 版本,是吗?


关于

“why can't it simply (in effect) redefine evaluated functions to be their computed value?”

嗯,总的来说不是那么容易。这些值必须存储在某个地方。即使对于 Int 值函数,您也不能只分配一个包含所有可能值的数组——它不适合内存。列表解决方案仅有效,因为 Haskell 是惰性的,因此允许无限列表,但这并不是特别令人满意,因为查找是 O(n ). 对于其他类型,这简直是无望的——你需要以某种方式对角化一个过度可数的无限域。

你需要一些更聪明的组织。我不知道 Mathematica 是如何做到这一点的,但它可能使用了很多“专有魔法”。对于任何输入,我不太确定它是否真的按照您想要的方式工作。

Haskell 幸运的是有类型 classes,这些允许你准确地表达一个类型需要什么才能快速记忆。 HasTrie就是这样一个class.