Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 从上一个表达式创建一个没有指针的新表达式_Haskell - Fatal编程技术网

Haskell 从上一个表达式创建一个没有指针的新表达式

Haskell 从上一个表达式创建一个没有指针的新表达式,haskell,Haskell,我正在读这本书,试图找出这两种功能之间的区别: 此功能不会记忆中间编号: fib_mem :: Int -> Integer fib_mem = (map fib [0..] !!) where fib 0 = 1 fib 1 = 1 fib n = fib_mem (n-2) + fib_mem (n-1) 这不是: fib_mem_arg :: Int -> Integer fib

我正在读这本书,试图找出这两种功能之间的区别:

此功能不会记忆中间编号:

fib_mem :: Int -> Integer
fib_mem = (map fib [0..] !!)
            where fib 0 = 1
                  fib 1 = 1
                  fib n = fib_mem (n-2) + fib_mem (n-1) 
这不是:

fib_mem_arg :: Int -> Integer
fib_mem_arg x = map fib [0..] !! x
                where fib 0 = 1
                      fib 1 = 1
                      fib n = fib_mem_arg (n-2) + fib_mem_arg (n-1) 
作者试图解释如下:

运行fib_mem_arg时,除了非常小的参数外,任何东西都可以 确认它没有回忆录。即使我们可以看到地图上的谎言 [0..]不依赖于参数编号,可以记忆, 它不会是,,因为对函数应用参数将创建 不能隐式具有表达式指针的新表达式 来自以前的函数应用程序

他这句粗体字是什么意思?有人能给我举个简单的例子吗

为什么
fib_mem
是一种
常量应用形式

为什么
fib\u mem
是一种恒定的应用形式

不是
fib\u mem
,而是
(映射fib[0..!!)
。这是因为它是一个部分应用的函数
(!!)
。因此,它受内存保留的影响

(另见:)

由于该类型是单态的,因此即使在调用
fib_mem
之间,它也会保留在内存中,实际上就像将fib[0..]映射到顶层一样,就像定义为

fib_mem_m :: Int -> Integer
fib_mem_m = (the_list !!)
            where fib 0 = 1
                  fib 1 = 1
                  fib n = (the_list !! (n-2)) + (the_list !! (n-1))
the_list = map fib [0..]
fib_mem_p :: Num a => Int -> a
fib_mem_p = (the_list !!)
            where fib 0 = 1
                  fib 1 = 1
                  fib n = (the_list !! (n-2)) + (the_list !! (n-1))
                  the_list = map fib [0..]
如果类型是多态的,则不可能浮到顶层,但在每次调用
fib_mem
期间,它仍然会被保留,就像定义为

fib_mem_m :: Int -> Integer
fib_mem_m = (the_list !!)
            where fib 0 = 1
                  fib 1 = 1
                  fib n = (the_list !! (n-2)) + (the_list !! (n-1))
the_list = map fib [0..]
fib_mem_p :: Num a => Int -> a
fib_mem_p = (the_list !!)
            where fib 0 = 1
                  fib 1 = 1
                  fib n = (the_list !! (n-2)) + (the_list !! (n-1))
                  the_list = map fib [0..]
要查看差异,请在GHCi propt处对fib\u mem\u m 10000进行两次评估。第二次尝试将花费0秒。但是,
fib_mem_p 10000
每次调用它都需要相同的时间。它仍然会像第一个一样快,所以仍然有记忆在那里进行,只是在通话之间没有保留

有了这种定义风格,在
fib_mem_arg
中的完整应用程序也将被存储——正如上面的一样,不是在调用
fib_mem_arg
之间,而是仅在每次调用期间

fib_mem_arg :: Num a => Int -> Integer  -- or polymorphic, makes no difference
fib_mem_arg x = the_list !! x
            where fib 0 = 1
                  fib 1 = 1
                  fib n = (the_list !! (n-2)) + (the_list !! (n-1))
                  the_list = map fib [0..]

但是这个粗体的句子是错误的!毕竟,
fib_mem 30000
fib_mem 30001
都是函数对参数的应用,但后者隐含着指向前者的指针,因此无论您先做哪一个,都需要更长的时间。他们把矛头指向了错误的问题!另请参见:。@DanielWagner也许一个简单的例子也不错。为什么这是一个CAF
z=(+)4
,而这不是
z=\x->4+x
?有什么不同?根据定义,lambda表达式不是CAF。这就是wiki页面所说的。超级组合器对于我来说就像函数组合,例如
h(g(fx))
。这是对的吗?为什么
zn=[1..n]
不是CAF
n
是一个绑定变量。
h(g(f x))
是一个包含大量自由变量的表达式。您需要显示等式(定义)的左侧在
z n=[1..n]
中,RHS上的
n
取决于LHS上的
n
,因此
z
不是CAF。实际上,它可以先称为
z5
,然后再称为
z3
。这将是两个不同的值,而不是一个。