Разница между списком и списком * в ракетке - PullRequest
2 голосов
/ 22 апреля 2020

Читая:

https://docs.racket-lang.org/reference/pairs.html

Я встречал list*

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

Что означает: «последний аргумент используется в качестве хвоста результата вместо конечного элемента»? Я думал, что списки всегда заканчиваются пустым списком: '()

И если: «Результатом является список, только если последний аргумент является списком», тогда что еще это? я думал, что все в схеме - список.

1 Ответ

7 голосов
/ 22 апреля 2020

Возможно, имеет смысл думать о list* не как о вариации list, а как о вариации cons.

> (cons 1 (list 2 3 4))
(list 1 2 3 4)
> (list* 1 (list 2 3 4))
(list 1 2 3 4)

При 2 аргументах (list* fst rst) создает то же самое, что и (cons fst rst).

Когда есть больше аргументов, list* добавляет их все как версию с несколькими аргументами cons.

> (cons 1 (cons 2 (cons 3 (list 4 5))))
(list 1 2 3 4 5)
> (list* 1 2 3 (list 4 5))
(list 1 2 3 4 5)

И так же, как cons не создаст правильный список, если вы передадите что-то еще как «rest», list* сделает то же самое.

> (equal? (cons 1 2) (list* 1 2))
#true
> (equal? (cons 1 (cons 2 3)) (list* 1 2 3))
#true

Эти вещи являются вымышленными, но не являются правильными списками.

Но наиболее распространенное использование list* должно использовать правильный список в качестве последнего аргумента. Если вы ищете отношение к list, то

> (list* 1 2 3 4 '())
(list 1 2 3 4)

Использование list* с '() в качестве последнего аргумента будет эквивалентно list без этого.

...