2017-01-06 3 views
1

Я работаю с простыми списками в Racket, и я выполнял функцию, чтобы суммировать элементы списка.Сумма элементов в списке Ракетка

Но я хотел бы знать, есть ли более простой способ сделать это.

Я сделал это функцию:

(define (mySum L) 
    (if (empty? L) 0 
     (+ (first L) (mySum (rest L)))) 
) 

выход:

(mySum '(1 2 3 4)) 
10 

Я хотел бы знать, если кто-нибудь знает более простой способ сделать это. Я объясняю себе, например: Это еще одна функции я сделал:

(define (myAppend L1 L2) 
    (if (empty? L1) L2 
     (cons (car L1) (myAppend (cdr L1) L2))) 
) 

Но эта функция может быть сделано более просто делать только это:

(define (myAppend L1 L2) 
    (append L1 L2) 
) 

Моей проблемы заключается в знаете, есть ли более простой способ сделать сумму элементов в списке. Благодаря

ответ

2

Если все, что вы собираетесь на это короткая программа,

(define (mySum L) 
    (apply + L)) 

короче. Будь то «проще» - это вопрос интерпретации. То, как вы написали, кажется «более простым» в том смысле, что оно определяется исключительно на основе структуры списков, тогда как (apply + L) полагается как на полумагическую функцию (apply), так и на полу-причудливое поведение + (тот факт, что он принимает переменное количество аргументов), который сам должен сделать нечто похожее на то, что вы уже написали.

(Кстати, я бы не назвал ваш myAppend пример проще, либо - первый на самом деле определяет функцию, которую вы хотите, в то время как второй раз относится к поведению вы хотите, что, в свою очередь, должен был Если вы делаете это как часть практической программы, (apply + L) и используя встроенный append, безусловно, путь, но если это для образовательных целей, то я думаю, что исходные версии обеих функций превосходят .)

+0

Спасибо за обмен своими знаниями! –

1

Также можно использовать for/sum:

(define (my+ L) 
    (for/sum ((i L)) 
    i)) 

(my+ '(1 2 3 4)) ; => 10 

«имени пусть» версия похожа на рекурсивные функции, но может быть легче понять:

(define (myplus L) 
    (let loop ((L L) 
      (s 0)) 
    (cond 
     [(empty? L) s] 
     [else (loop (rest L) 
        (+ s (first L)))]))) 

«конд» также могут быть заменены на «если» здесь, так как есть только два случая. Ключевое слово 'else' также может быть опущено.

2

Другой способ приблизиться было бы

(define (my-sum lst) 
(foldr + 0 lst)) 

Это использует встроенную функцию foldr и довольно коротким. Foldr использует функцию (+), базовый регистр (0) и список (lst). Я прикрепил ссылку к визуальному представлению foldr, а также ссылку, которая объясняет это очень хорошо.

link

Дополнительная информация here

+0

Некоторое интересное обсуждение здесь также находится http://stackoverflow.com/questions/39018163/expanded-form-of-fold-in-racket. – rnso

1
(apply + '(elements_of_list)) 

:)

+2

Было бы лучше, если бы вы объяснили, почему и как этот код решает проблему. Форматирование кода также приятно. Это ':)' часть кода? – brasofilo