2014-11-08 4 views
1

Я начал работать над своей первой функцией ракетки, но есть большая проблема.Ракетка простая последовательность функции генератора int

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

Я понимаю, но почему мой код не работает? Кто-нибудь может мне помочь?

Ответ на Оскар действительно замечательный) Спасибо, дорогой друг.

ответ

5

Прежде всего, эта функция уже существует в рэкет, и это называется range:

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

Теперь о вашей реализации вы должны помнить, что список операций в схеме делать не изменять списки на месте , В частности, эта линия не делает то, что вы себе представить:

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

Конечно, append добавил новый элемент, но он вернулся в новый список, и потому, что вы не храните его в качестве переменной или передавать его как параметр, который был утрачен. Кроме того, лучше использовать cons для построения выходного списка, используя append, что приведет к квадратичной производительности. Кроме того, есть ошибка здесь:

[(begin ((

Смотрите те двойной [( и (( там? они вызывают ошибку "application: not a procedure". В схеме окружающее выражение с () означает функция-приложение - круглые скобки не, которые будут использоваться для определения блоков кода, так как вы использовали бы {} на других языках программирования. Правильная реализация с нуля следует, ближе к тому, что вы имели в виду и сохраняя такое же поведение, как 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 '() 

Он работает, как ожидалось:

(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) 
+1

Спасибо большое, есть так маш ошибки в небольшой кусок кода. Это действительно крутой ответ. –

+0

похоже, что я идиот, но в моей рэкете он не работает ... Я ничего не понимаю ... –

+1

@ РоманИванов Что такое сообщение об ошибке? убедитесь, что первая строка в файле говорит «#lang racket» и что язык, выбранный в параметрах, «определяет язык из источника». –

Смежные вопросы