Мне было интересно, есть ли способ взять список чисел (цифр) и обрезать числа вместе, чтобы получить одно большое число (не сложение) в схеме. Например, я хотел бы
(foo '(1 2 3 4))
;=> 1234
Есть ли в Scheme встроенная функция для этого?
Мне было интересно, есть ли способ взять список чисел (цифр) и обрезать числа вместе, чтобы получить одно большое число (не сложение) в схеме. Например, я хотел бы
(foo '(1 2 3 4))
;=> 1234
Есть ли в Scheme встроенная функция для этого?
В семейство Scheme входит несколько языков, а также несколько версий Scheme. Если вы используете один, например, Racket, который включает в себя левую ассоциативную складку (часто называемую foldl
, fold
или reduce
, хотя есть и другие варианты), это довольно просто реализовать с точки зрения сгиба. Складки более подробно описаны в следующих вопросах и ответах:
fold
можно рассматривать как итеративный конструкция (а в схеме, которая требует оптимизации хвостовых вызовов, компилируется в итеративный код), а также включает реализацию foldl
для схем, в которых ее нет.reduce
предоставляет несколько более удобный интерфейс, чем тот, который предоставляется в некоторых библиотеках Scheme.Вот как выглядит код с точки зрения foldl
:
(define (list->num digits)
(foldl (lambda (digit n)
(+ (* 10 n) digit))
0
digits))
> (list->num '(1 2 3 4))
1234
Если в вашем языке нет этого, foldl
довольно легко написать (например, мой ответ на вопрос из приведенных выше вопросов включает реализацию) и используйте предыдущий код, или вы можете написать всю функцию (используя тот же подход) самостоятельно:
(define (list->num-helper digits number-so-far)
(if (null? digits)
number-so-far
(list->num-helper (cdr digits)
(+ (* 10 number-so-far)
(car digits)))))
(define (list->num digits)
(list->num-helper digits 0))
Вы можете сделать это немного более кратким, используя имя let
:
(define (list->num digits)
(let l->n ((digits digits)
(number 0))
(if (null? digits)
number
(l->n (cdr digits)
(+ (* 10 number)
(car digits))))))
fold-left
в rnrs lists
библиотеке
- person Sylwester; 24.10.2013
loop
на l->n
, чтобы избежать путаницы.
- person Joshua Taylor; 24.10.2013
reduce
- person Joshua Taylor   schedule 24.10.2013