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

时间:2014-11-08 11:49:18

标签: functional-programming scheme 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)))

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

(define (sequence low high stride)
   (if (> low high)
     null
     (cons low  (sequence (+ low stride) high stride))))

我理解但为什么我的代码不起作用?有人能帮助我吗?

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

1 个答案:

答案 0 :(得分:5)

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

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

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

(append (list low) list-of-int)

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

[(begin ((

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

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 '()