我试图理解迭代器。我注意到Python documentation认为迭代器是一个函数样式构造。我不太明白。在
迭代器内部有一个状态,这不是真的吗。所以当你调用it.__next__()
时,你改变了迭代器的状态。据我所知,对象的变化状态不被认为是函数式的,因为函数式编程强调对象/闭包的不变性和组合能力。在
实际上,出现这个问题是因为我想编写一个Scheme过程/函数,它接受令牌并返回迭代器。 在
(define tokens->iterator
(lambda ls
(lambda ()
(if (null? ls)
'*eoi*
(let ((tok (car ls)))
(set! ls (cdr ls))
tok)))))
注意我必须使用set!
来改变ls
,这就是我提出这个问题的方式。在
使用它, 在
^{pr2}$为了测试它, 在
scheme@(guile-user)> (it)
$2 = 1
scheme@(guile-user)> (it)
$3 = +
scheme@(guile-user)> (it)
$4 = 2
scheme@(guile-user)> (it)
$5 = *eoi*
scheme@(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*'
有人能澄清一下吗?顺便说一句,我使用的是python3和Guile-Scheme,以防有人有兴趣尝试这些示例。在
你的观点很好。迭代器当然不是“纯功能的”,这个术语通常用来描述完全不使用变异的习惯用法。更宽泛的术语“functional”的定义更为宽松,它表示使用相对较少变异的程序,这些程序使用高阶和一级函数,而且可能最广泛的是,“使用看起来不像C的奇怪抽象。”
坦率地说,我认为我应该把迭代器称为函数迭代器。那就是:我同意你的观点。在
函数式的样式是作为一个整体处理数据列表,而不是一个可以随意更改的值集合。例如,如果您有一个数字列表,并且要更改第三个元素,则非功能性方法是直接更改它:
函数式方法是编写一个接受原始序列的函数,并返回一个包含所做更改的新列表,而原始列表保持不变。在
^{pr2}$这两个迭代器都不是纯功能的,因为它们确实保持可变状态,尽管被视为黑匣子,但您可以在功能上使用它们,因为迭代器的用户不能直接影响该状态。在
纯函数迭代器是一个函数,它将list和当前状态作为输入,并返回一个值和一个新状态以传递给函数的下一个调用。在
相关问题 更多 >
编程相关推荐