Я пытаюсь понять итератор. Я замечаю документацию Python, считает iterator конструкцией функционального стиля. Я этого не понимаю.
Не правда ли, что итератор имеет внутри него. Поэтому, когда вы вызываете it.__next__()
, вы мутируете состояние итератора. Насколько мне известно, мутировавшее состояние объекта не считается функциональным, поскольку функциональное программирование подчеркивает неизменность и способность компоновки объекта/закрытия.
На самом деле проблема возникает из-за того, что я хочу написать процедуру/функцию Scheme, которая принимает токены и возвращает итератор.
(define tokens->iterator
(lambda ls
(lambda ()
(if (null? ls)
'*eoi*
(let ((tok (car ls)))
(set! ls (cdr ls))
tok)))))
Обратите внимание, что я должен использовать set!
для мутирования ls
, вот как я поднимаю этот вопрос.
Чтобы использовать его,
(define it (tokens->iterator 1 '+ 2))
Чтобы проверить это,
[email protected](guile-user)> (it)
$2 = 1
[email protected](guile-user)> (it)
$3 = +
[email protected](guile-user)> (it)
$4 = 2
[email protected](guile-user)> (it)
$5 = *eoi*
[email protected](guile-user)> (it)
$6 = *eoi*
Просто для удовольствия, я также перевести это на Python:
def tokens_to_iterator(*tup):
ls = list(tup)
def iterator():
if not ls:
return "*eoi*"
else:
tok = ls.pop(0)
return tok
return iterator
Аналогично, метод pop() удаляет и возвращает первый элемент, изменяя список.
Чтобы использовать его,
it = tokens_to_iterator(1, "+", 2)
Чтобы проверить это,
>>> it()
1
>>> it()
'+'
>>> it()
2
>>> it()
'*eoi*'
>>> it()
'*eoi*'
Может ли кто-нибудь разъяснить это? Кстати, я использую Python 3 и Guile Scheme на случай, если кто-то заинтересован в том, чтобы попробовать примеры.