球拍简单的int生成器函数序列

Ром*_*нов 1 scheme functional-programming racket

我已经开始研究我的第一个球拍功能,但是有一个很大的问题.

(define (sequence low hide stride)
   (letrec ([list-of-int null])
          (define (f low hide stride)
           (if (< low hide)
              [(begin ((append (list low) list-of-int)
                (f (+ low stride) hide stride)))]
              [list-of-int]))
     (f low hide stride)))
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮助我理解我的球拍吗?在我看来,它看起来很好,但不起作用.我在互联网上找到了更简单的解决方案:

(define (sequence low high stride)
   (if (> low high)
     null
     (cons low  (sequence (+ low stride) high stride))))
Run Code Online (Sandbox Code Playgroud)

我理解但为什么我的代码不起作用?有谁能够帮我?

奥斯卡回答真的很棒)非常感谢亲爱的朋友.

Ósc*_*pez 5

首先,这个功能已经存在于Racket中,它被称为range:

(range 1 11 1)
=> '(1 2 3 4 5 6 7 8 9 10)
Run Code Online (Sandbox Code Playgroud)

现在,关于您的实现,您必须记住Scheme中的列表操作不会就地修改列表.特别是,这条线没有做你想象的那样:

(append (list low) list-of-int)
Run Code Online (Sandbox Code Playgroud)

果然,append添加了一个新元素,但是它返回了一个新列表,并且因为你没有将它存储为变量或者将它作为参数传递给修改丢失了.此外,最好使用cons构建输出列表,使用append将导致二次性能.此外,这里有一个错误:

[(begin ((
Run Code Online (Sandbox Code Playgroud)

看到那些双重[(((那里?它们导致"application: not a procedure"报告错误.在Scheme中,使用()均值函数应用程序包围表达式- 括号用于定义代码块,就像{}在其他编程语言中一样.从头开始正确实现,更接近您的想法并保留相同的行为range:

(define (sequence low high stride)
  (define (f low cmp acc)    ; lower bound, comparator and accumulator
    (if (cmp high low)       ; exit condition for base case
        (reverse acc)        ; reverse and return the accumulator
        (f (+ low stride)    ; advance lower bound
           cmp               ; pass the comparator
           (cons low acc)))) ; build the list
  (if (positive? stride)     ; if the step is positive
      (f low <= '())         ; initialize with <= comparator and '()
      (f low >= '())))       ; else initialize with >= and '()
Run Code Online (Sandbox Code Playgroud)

它按预期工作:

(sequence 1 11 1)
=> '(1 2 3 4 5 6 7 8 9 10)

(sequence 1 12 2)
=> '(1 3 5 7 9 11)

(sequence 10 0 -1)
=> '(10 9 8 7 6 5 4 3 2 1)
Run Code Online (Sandbox Code Playgroud)