标准化函数而不实际在 Haskell 中应用它

Pos*_*cat 6 evaluation haskell lambda-calculus normalization

我想在不应用它的情况下评估一个函数的正常形式,例如,

\n -> n + sum [1..100]
Run Code Online (Sandbox Code Playgroud)

应该被评估为

\n -> n + 5050
Run Code Online (Sandbox Code Playgroud)

但是没有NFData函数的实例,这是合理的,因为我们无法获得函数的子项。

我想知道是否有可能在一些编译器魔法的帮助下完全规范化一个函数。

Dan*_*ner 5

不,这是不可能的。然而,在大多数情况下,它是不需要的。我怀疑您缺少的技巧是取消不依赖于通过 let 输出的昂贵计算。相比:

-- recomputes `sum [1..100]` each time you apply it to an argument
f1 :: Int -> Int
f1 n = n + sum [1..100]

-- computes `sum [1..100]` just once, then uses the "cached" result each time
-- you apply it to an argument
f2 :: Int -> Int
f2 = let s = sum [1..100] in \n -> n + s
Run Code Online (Sandbox Code Playgroud)

f1每次使用函数都是昂贵的。函数f2第一次使用时很昂贵,但之后每次都便宜。

(此答案特定于 GHC。其他编译器(如果存在)可能会有所不同。)