通过重复输入/迭代列出定义

时间:2017-02-12 13:47:51

标签: list haskell recursion

我想根据初始元素0定义Thue-Morse Sequence(或fair-sharing sequence),并根据整个元素定义列表的下一部分的规则列出直到这一点。即。

fair 0 = [0]
--fair 1 = [0,1]
--fair 2 = [0,1,1,0]
--fair 3 = [0,1,1,0,1,0,0,1]
fair n = fair (n - 1) ++ map (1-) (fair (n - 1))

这可以很好地生成任何预定义长度的列表,但不仅一次定义整个列表似乎无效,如果我需要预定义的数量,则使用take

我第一次定义整个列表的尝试是fair = 0 : map (1-) fair但当然,这会填充列表,因此它不会(需要)重新输入列表(并返回[0,1,0,1,0,1...] )。我想要的是一些定义列表的方法,以便当它到达列表中尚未定义的元素时,它通过重新输入列表直到那个点来定义下一个“块”,(而不是计算'追逐'新值的产生),所以计算列表的步骤将类似于这个过程:

  • 从初始列表开始,[0]
  • (1-)映射到现有列表,生成[1]
  • 将此附加到现有列表,生成[0,1]
  • (1-)映射到现有列表,生成[1,0]
  • 将此附加到现有列表,生成[0,1,1,0]
  • (1-)映射到现有列表,生成[1,0,0,1]
  • 将此附加到现有列表,生成[0,1,1,0,1,0,0,1]

我上面链接的Wikipedia article有一个helpful gif来说明这个过程。

正如我认为你可以看到的,当需要新元素时,这将无限期地持续下去。但是,我不能为我的生活找到一种在递归函数中成功编码的方法。

我试过了

reenter f xs = reenter f (xs ++ map f xs)
fair = reenter (1-) [0]

但是虽然逻辑似乎是正确的,但它没有产生任何东西,可能是由于立即递归调用(尽管我认为haskell的懒惰评估可能会解决这个问题,尽管它是一个相当复杂的情况)。

2 个答案:

答案 0 :(得分:3)

正如您所说,您无法立即执行递归调用 - 您首先需要返回下一个结果,然后递归调用,就像上次尝试一样:

Prelude> reenter prev_list = inverted_prev_list ++ reenter (prev_list ++ inverted_prev_list) where inverted_prev_list = map (1-) prev_list
Prelude> f = [0] ++ reenter [0]
Prelude> take 20 f
[0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1]

答案 1 :(得分:1)

以下是另一种函数编程语言Racket中的代码,使用问题中列出的步骤。

(define (f n)

  (define (invert s)            ; sub-function to invert the numbers
    (list->string
     (for/list ((i (string->list s)))
       (if (equal? i #\0) #\1 #\0))))

  (let loop ((c 1)
             (s "0"))           ; starting string is "0"
    (if (> c n)
        s
        (loop (add1 c)
              (string-append s (invert s))))))

测试:

(f 1)
(f 2)
(f 3)
(f 4)
(f 5)

输出:

"01"
"0110"
"01101001"
"0110100110010110"
"01101001100101101001011001101001"

对于无限系列:

(define (f)
  (define (invert s)
    (list->string
     (for/list ((i (string->list s)))
       (if (equal? i #\0) #\1 #\0))))

  (let loop ((s "0"))
    (define ss (string-append s (invert s)))
    (println ss)
    (loop ss)))

运行:

(f)

这可能会给出一些关于Haskell解决这个问题的想法。