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
List 为什么这个递归映射函数只应用于列表中的最后两个元素?_List_Haskell_Lazy Evaluation_Map Function_Lazy Sequences - Fatal编程技术网

List 为什么这个递归映射函数只应用于列表中的最后两个元素?

List 为什么这个递归映射函数只应用于列表中的最后两个元素?,list,haskell,lazy-evaluation,map-function,lazy-sequences,List,Haskell,Lazy Evaluation,Map Function,Lazy Sequences,这就是给定的问题:以下列表中的前8个元素是什么 mystery = 0 : 10 : (map(+1)mystery) 答案是[0,10,1,11,2,12,3,13…] 但我认为答案应该是[0,10,1,11,1,11,2,12]。以下步骤说明了原因: 1我们被给予;list[0,10]因此,在第一次应用函数后,我们得到list[0,10,1,11] 2现在我们有一个列表[0,10,1,11],所以再次应用函数后,结果列表应该是[0,10,1,11,1,11,2,12] 显然情况并非如此。有

这就是给定的问题:以下列表中的前8个元素是什么

mystery = 0 : 10 : (map(+1)mystery)
答案是[0,10,1,11,2,12,3,13…]

但我认为答案应该是[0,10,1,11,1,11,2,12]。以下步骤说明了原因:

1我们被给予;list[0,10]因此,在第一次应用函数后,我们得到list[0,10,1,11] 2现在我们有一个列表[0,10,1,11],所以再次应用函数后,结果列表应该是[0,10,1,11,1,11,2,12]


显然情况并非如此。有人能解释一下原因吗?

让我们用map的递归定义来研究一下:

既然我们有

mystery = 0:10:(map (+1) mystery)
我们已经知道了

mystery = [0, 10, ...]
还有。。。代表地图+1神秘。让我们使用上面的定义来计算它

我们应用它的列表显然不是空的——它以0和10开头。所以我们使用第二行,x为0,xs为10:map+1:

或者,对第一级嵌套再次使用公式:

map (+1) mystery = 1:11:(map (+1) (map (+1) mystery))
那么,回到神秘本身,我们现在知道它的前4个元素:

mystery = [0, 10, 1, 11, ...]
还有。。。代表地图+1地图+1神秘的内容。也就是说,基于上述结果:

map (+1) (1:11:(map (+1) (map (+1) mystery)))

在这里,我将不告诉你评估的细节,因为现在应该清楚发生了什么:神秘中第5和第6个元素的前2个元素将是2和12,其余元素将是地图+1地图+1地图+1神秘。通过完全相同的过程,从3和13开始。就你所能计算的范围而言,它还在继续。

让我们使用map的递归定义来完成它:

既然我们有

mystery = 0:10:(map (+1) mystery)
我们已经知道了

mystery = [0, 10, ...]
还有。。。代表地图+1神秘。让我们使用上面的定义来计算它

我们应用它的列表显然不是空的——它以0和10开头。所以我们使用第二行,x为0,xs为10:map+1:

或者,对第一级嵌套再次使用公式:

map (+1) mystery = 1:11:(map (+1) (map (+1) mystery))
那么,回到神秘本身,我们现在知道它的前4个元素:

mystery = [0, 10, 1, 11, ...]
还有。。。代表地图+1地图+1神秘的内容。也就是说,基于上述结果:

map (+1) (1:11:(map (+1) (map (+1) mystery)))

在这里,我将不告诉你评估的细节,因为现在应该清楚发生了什么:神秘中第5和第6个元素的前2个元素将是2和12,其余元素将是地图+1地图+1地图+1神秘。通过完全相同的过程,从3和13开始。所以,继续下去,就在你潜入神秘定义之前,让我们来看看一个规律图: 这一法律的非正式证明很容易遵循:

map f (map g [x1, x2, ..., xn]) == map f [g x1, g x2, ..., g xn]
                                == [f (g x1), f (g x2), ..., f (g xn)]
                                == [(f.g) x1, (f.g) x2, ..., (f.g) xn]
                                == map (f.g) [x1, x2, ..., xn]
考虑到这一点,让我们一步一步地展开谜团:

mystery == 0 : 10 : map (+1) mystery
        -- by definition of mystery
        == 0 : 10 : map (+1) (0 : 10 : map (+1) mystery)
        -- by definition of map and the fact that  0 + 1 == 1
        == 0 : 10 : 1 : map (+1) (10 : map (+1) mystery)
        -- by definition of map and the fact that 10 + 1 == 11
        == 0 : 10 : 1 : 11 : map (+1) (map (+1) mystery)
        -- using the law above, and the fact that (+1) . (+1) == (+2)
        == 0 : 10 : 1 : 11 : map (+2) mystery
        == 0 : 10 : 1 : 11 : map (+2) (0 : 10 : map (+1) mystery)
        == 0 : 10 : 1 : 11 : 2 : map (+2) (10 : map (+1) mystery)
        == 0 : 10 : 1 : 11 : 2 : 12 : map (+2) (map (+1) mystery)
        == 0 : 10 : 1 : 11 : 2 : 12 : map (+3) mystery
        -- etc
你不能从一个有限的列表[0,10]开始;从一个以0和10开头的无限列表开始,其余元素以递归方式定义

在某种意义上,列表没有封闭的形式,但这并不重要;懒惰意味着你们只在需要的时候将地图应用于神秘,以获得所需的物品。例如,head-summary和head-tail-summary都不需要评估对map的调用,head-tail-summary只需要将+1映射到head-summary,而不是整个无限列表


懒惰模糊了列表和计算列表的算法之间的区别。

在跳入神秘定义之前,让我们来看看其中的一个法则映射:

这一法律的非正式证明很容易遵循:

map f (map g [x1, x2, ..., xn]) == map f [g x1, g x2, ..., g xn]
                                == [f (g x1), f (g x2), ..., f (g xn)]
                                == [(f.g) x1, (f.g) x2, ..., (f.g) xn]
                                == map (f.g) [x1, x2, ..., xn]
考虑到这一点,让我们一步一步地展开谜团:

mystery == 0 : 10 : map (+1) mystery
        -- by definition of mystery
        == 0 : 10 : map (+1) (0 : 10 : map (+1) mystery)
        -- by definition of map and the fact that  0 + 1 == 1
        == 0 : 10 : 1 : map (+1) (10 : map (+1) mystery)
        -- by definition of map and the fact that 10 + 1 == 11
        == 0 : 10 : 1 : 11 : map (+1) (map (+1) mystery)
        -- using the law above, and the fact that (+1) . (+1) == (+2)
        == 0 : 10 : 1 : 11 : map (+2) mystery
        == 0 : 10 : 1 : 11 : map (+2) (0 : 10 : map (+1) mystery)
        == 0 : 10 : 1 : 11 : 2 : map (+2) (10 : map (+1) mystery)
        == 0 : 10 : 1 : 11 : 2 : 12 : map (+2) (map (+1) mystery)
        == 0 : 10 : 1 : 11 : 2 : 12 : map (+3) mystery
        -- etc
你不能从一个有限的列表[0,10]开始;从一个以0和10开头的无限列表开始,其余元素以递归方式定义

在某种意义上,列表没有封闭的形式,但这并不重要;懒惰意味着你们只在需要的时候将地图应用于神秘,以获得所需的物品。例如,head-summary和head-tail-summary都不需要评估对map的调用,head-tail-summary只需要将+1映射到head-summary,而不是整个无限列表

懒惰模糊了列表和计算列表的算法之间的区别。

mystery = 0 : 10 : map (+1) mystery
根据定义!!和:地图是这样的

mystery !! 0 = 0          -- pseudocode
mystery !! 1 = 10
mystery !! n | n > 1
             = (0 : 10 : map (+1) mystery) !! n
             = (10 : map (+1) mystery) !! (n-1)
             = (map (1+) mystery) !! (n-2)
             = 1 + (mystery !! (n-2))
这就是你的答案

举例说明:

--         0   1  2   3  4   5  6        -- n
mystery = [0, 10, 1, 11, 2, 12, 3, ...
--               /   /  /   /  /         -- (+1)
--              [0, 10, 1, 11, 2, ...
--               0   1  2   3  4         -- n-2
所以所有这些都是,每个元素都是根据前面的一个,前面的两个位置来定义的

因此,另一种写下相同内容的方法是,使配对不压缩显式

mystery = 0 : 10 : zipWith (+) (repeat 1)
                               mystery
-- and in general,
-- map (f y) xs  ==  zipWith f (repeat y) xs 
该程序被翻译成命令伪代码

main = print mystery
实际上和

main :
    a = 0
    b = 10
    print "[" 
    while( True ) :
       print a , 
       print b ,
       a += 1
       b += 1
解决此类问题的一个原则性方法是命名所有临时实体,即此处惰性数据构造函数背后的内部thunk:,当它们产生时,由于惰性评估的要求,它们被迫进入WHNF。然后神秘消失了:

mystery = 0  : 10 : map (+1) mystery
        = x1 : t1 
  where 
  x1 = 0
  t1 = 10 : map (+1) mystery
     = x2 : t2
    where
    x2 = 10
    t2 = map (+1) mystery
       = map (+1) (x1 : t1)
       = x1 + 1 : map (1+) t1         -- by definition of map
       = x3     : t3
      where
      x3 = x1 + 1 = 0 + 1 = 1
      t3 = map (1+) t1 = map (1+) (x2 : t2)
         = x2 + 1 : map (1+) t2       --    = x_{n} + 1 : ...
         = x4     : t4                --    = x_{n+2}   : ...
        where
        ....
在任何时候我们都不能得到任何函数o 在这个还原过程中,没有超过1+的元素,我们也不会得到一个以上的元素排成一行

我们得到的是xn:=1+xn-2,重复地,对于大于1的所有n。

mystery = 0 : 10 : map (+1) mystery
根据定义!!和:地图是这样的

mystery !! 0 = 0          -- pseudocode
mystery !! 1 = 10
mystery !! n | n > 1
             = (0 : 10 : map (+1) mystery) !! n
             = (10 : map (+1) mystery) !! (n-1)
             = (map (1+) mystery) !! (n-2)
             = 1 + (mystery !! (n-2))
这就是你的答案

举例说明:

--         0   1  2   3  4   5  6        -- n
mystery = [0, 10, 1, 11, 2, 12, 3, ...
--               /   /  /   /  /         -- (+1)
--              [0, 10, 1, 11, 2, ...
--               0   1  2   3  4         -- n-2
所以所有这些都是,每个元素都是根据前面的一个,前面的两个位置来定义的

因此,另一种写下相同内容的方法是,使配对不压缩显式

mystery = 0 : 10 : zipWith (+) (repeat 1)
                               mystery
-- and in general,
-- map (f y) xs  ==  zipWith f (repeat y) xs 
该程序被翻译成命令伪代码

main = print mystery
实际上和

main :
    a = 0
    b = 10
    print "[" 
    while( True ) :
       print a , 
       print b ,
       a += 1
       b += 1
解决此类问题的一个原则性方法是命名所有临时实体,即此处惰性数据构造函数背后的内部thunk:,当它们产生时,由于惰性评估的要求,它们被迫进入WHNF。然后神秘消失了:

mystery = 0  : 10 : map (+1) mystery
        = x1 : t1 
  where 
  x1 = 0
  t1 = 10 : map (+1) mystery
     = x2 : t2
    where
    x2 = 10
    t2 = map (+1) mystery
       = map (+1) (x1 : t1)
       = x1 + 1 : map (1+) t1         -- by definition of map
       = x3     : t3
      where
      x3 = x1 + 1 = 0 + 1 = 1
      t3 = map (1+) t1 = map (1+) (x2 : t2)
         = x2 + 1 : map (1+) t2       --    = x_{n} + 1 : ...
         = x4     : t4                --    = x_{n+2}   : ...
        where
        ....
在这个归约过程中,除了1+之外,我们在任何时候都不会得到任何函数,也不会得到一排以上的函数


我们得到的是xn:=1+xn-2,对于1以上的所有n,重复使用。

当您在第一次应用函数后编写时,您声称应用了什么函数?为什么这个递归映射函数只应用于列表中的最后两个元素?。它被应用于列表中的每个元素,但只有一次-您的版本似乎将它应用于0和10两次,我不明白为什么您会认为它应该。此外,该列表是无限的,因此它没有最后2个元素您从来没有列表[0,10];您的列表以0和10开头,然后是。。。某物从概念上讲,您必须区分永远附加到有限列表,并将某个函数应用于初始无限列表的每个元素。首次应用该函数后编写时,您声称应用的确切函数是什么?为什么此递归映射函数仅应用于列表中的最后两个元素?。它被应用于列表中的每个元素,但只有一次-您的版本似乎将它应用于0和10两次,我不明白为什么您会认为它应该。此外,该列表是无限的,因此它没有最后2个元素您从来没有列表[0,10];您的列表以0和10开头,然后是。。。某物从概念上讲,您必须区分永远附加到有限列表和对最初无限列表的每个元素应用某些函数。很好的解释。应该提到的是,这解释了为什么神秘具有它所具有的价值,但它并没有解释神秘是如何被实际评估的。特别是,地图+1神秘度只计算一次,而不是每两个元素计算一次。很好的解释。应该提到的是,这解释了为什么神秘具有它所具有的价值,但它并没有解释神秘是如何被实际评估的。特别是,map+1神秘度只计算一次,而不是每两个元素计算一次。