1

我正在做 CIS 194 的作业。问题是使用streamInterleave. 代码看起来像

data Stream a = Cons a (Stream a)

streamRepeat :: a -> Stream a
streamRepeat x = Cons x (streamRepeat x)

streamMap :: (a -> b) -> Stream a -> Stream b
streamMap f (Cons x xs) = Cons (f x) (streamMap f xs)

streamInterleave :: Stream a -> Stream a -> Stream a
streamInterleave (Cons x xs) ys = Cons x (streamInterleave ys xs)

ruler :: Stream Integer
ruler = streamInterleave (streamRepeat 0) (streamMap (+1) ruler)

我真的很困惑为什么统治者可以这样实现。这是要给我[0,1,0,1....]吗?

任何帮助将不胜感激。谢谢!!

4

2 回答 2

2

首先,我们将表示一个Stream这样的:

a1 a2 a3 a4 a5 ...

现在,让我们来定义ruler分开:

ruler :: Stream Integer
ruler = streamInterleave (streamRepeat 0) (streamMap (+1) ruler)

在 Haskell 中,很重要的一点是懒惰。也就是说,在需要评估之前,不需要评估东西。这在这里很重要:这就是使这个无限递归定义起作用的原因。那么我们如何理解这一点呢?我们将从streamRepeat 0位开始:

0 0 0 0 0 0 0 0 0 ...

然后将其馈入 a ,它与来自(用s表示streamInterleave)的(尚未知的)流交错:streamMap (+1) rulerx

0 x 0 x 0 x 0 x 0 x 0 x ...

现在我们将开始填写那些xs。我们已经知道ruleris0的每个第二个元素,所以streamMap (+1) rulermust的每个第二个元素1

  1   x   1   x   1   x   1   x   1   x ... <--- the elements of (streamMap (+1) ruler)
0 1 0 x 0 1 0 x 0 1 0 x 0 1 0 x 0 1 0 x ... <--- the elements of ruler

现在我们知道每组四个中的第二个元素(所以数字 2,6,10,14,18,...)是1,所以对应的元素streamMap (+1) ruler必须是2

  1   2   1   x   1   2   1   x   1   2 ... <--- the elements of (streamMap (+1) ruler)
0 1 0 2 0 1 0 x 0 1 0 2 0 1 0 x 0 1 0 2 ... <--- the elements of ruler

现在我们知道,每组八中的每第四个元素(所以数字 4,12,20,...)是2这样对应的元素streamMap (+1) rulermust 是3

  1   2   1   3   1   2   1   x   1   2 ... <--- the elements of (streamMap (+1) ruler)
0 1 0 2 0 1 0 3 0 1 0 2 0 1 0 x 0 1 0 2 ... <--- the elements of ruler

我们可以ruler像这样无限n/2, 3n/2, 5n/2, ...地继续构建,将 的每个编号的值替换回去ruler

于 2019-03-25T20:45:39.310 回答
1

在 Haskell 表示法中,用[]代替Stream无限列表同构),

ruler = interleave (repeat 0) 
                   (map (+1) ruler)

[ruler !! i     | i <- [0..]]     == concat . transpose $
                                       [ repeat 0
                                       , map (+1) ruler]

ruler分成两个交替的子序列进行匹配,我们得到

[ruler !! 2*i   | i <- [0..]]     == repeat 0
                                  == [0 | i <- [0..]]         -- {0} --

[ruler !! 2*i+1 | i <- [0..]]     == map (+1) ruler
                                  == map (+1) $ concat . transpose $
                                       [ [ruler !! 2*i   | i <- [0..]]
                                       , [ruler !! 2*i+1 | i <- [0..]]]
concat . transpose $              == concat . transpose $
 [[ruler !! 2*i+1 | i <- [0,2..]]      [ [1 | i <- [0..]]
 ,[ruler !! 2*i+1 | i <- [1,3..]]]     , [1 + ruler !! 2*i+1 | i <- [0..]]]

再次分裂,

  [ruler !! 4*i+1 | i <- [0..]]   == [1 | i <- [0..]]         -- {1} --

  [ruler !! 4*i+3 | i <- [0..]]   == concat . transpose $
                                       [ [1 + ruler !! 2*i+1 | i <- [0,2..]]
                                       , [1 + ruler !! 2*i+1 | i <- [1,3..]]]

然后再次,

  [ruler !! 8*i+3 | i <- [0..]]   == [2 | i <- [0..]]         -- {2} --

  [ruler !! 8*i+7 | i <- [0..]]   == ....

您应该能够从这里看到它:

      .... 16*i+7             .....   3                       -- {3} --
      .... 32*i+15            .....   4                       -- {4} --
      .... 64*i+31            .....
      ....

因此,

    ruler !! 2^(k+1)*i + 2^k - 1   ==   k    ,  k <- [0..] ,  i <- [0..]

0: i => 2i
1:      2i+1 => 4i+1
2:              4i+3 => 8i+3
3:                      8i+7 => 16i+7
4:                              16i+15 => ....
5:                                     
于 2019-03-25T22:25:12.280 回答