部分应用程序与模式匹配:为什么这些Haskell函数的行为不同?

问题描述 投票:0回答:1

我想了解有关Haskell函数的一些知识。

首先,这是以典型的“慢速”方式定义的斐波那契函数(即没有记忆且没有无限列表技巧的递归方法)

slowfib :: Int -> Integer
slowfib 0 = 0
slowfib 1 = 1
slowfib n = slowfib (n-2) + slowfib (n-1)

[接下来,是该书的规范记忆版本。 (因为我更喜欢!!运算符的前缀版本,所以它与Tutorials / books / etc中的典型示例稍有不同。)

memfib = (!!) (map fib [0..])
  where
    fib 0 = 0
    fib 1 = 1
    fib k = memfib(k-2) + memfib(k-1)

上述解决方案使用(!!)运算符的部分应用,这是有道理的:我们希望memfib

最终成为带有参数的函数,并且在定义时不包含参数。

到目前为止,一切都很好。现在,我以为我可以编写一个等效的记忆功能,在定义中does

包含一个参数,所以我这样做了:
memfib_wparam n = ((!!) (map fib [0..])) n
  where
    fib 0 = 0
    fib 1 = 1
    fib k = memfib_wparam(k-2) + memfib_wparam(k-1)

((在Lambda演算术语中,memfib

memfib_wparams只是彼此的eta转换。我认为?)]

这可行,但是备忘录消失了。实际上,memfib_wparam

的表现甚至比showfib更差:不仅速度较慢,而且其内存使用量是其两倍多。)
*Main> slowfib 30
832040
(1.81 secs, 921,581,768 bytes)
*Main> memfib 30
832040
(0.00 secs, 76,624 bytes)
*Main> memfib_wparam 30
832040
(2.01 secs, 2,498,274,008 bytes)

这里发生了什么?更重要的是,我对Haskell函数定义出错的更广泛理解是什么?我以为我在memfib_wparam

中使用的语法只是我在memfib中所做的语法糖,但显然不是。

我试图了解有关Haskell函数的一些信息。首先,这是以典型的“慢”方式定义的斐波那契函数(即没有记忆的递归操作,也没有无限列表技巧)...

haskell functional-programming pattern-matching memoization partial-application
1个回答
0
投票

区别在于绑定fib函数的时间。

© www.soinside.com 2019 - 2024. All rights reserved.