我已经看到流被用作comonad的默认示例,但我不能完全确定它们是如何无限的,但不是。Haskell Streams(Comonadic):无限?
假设我们有数据的构造函数(from here)
data Stream a = a :> Stream a
我们如何最终完成从流?我们写在最后有没有定义?我知道这种语言是懒惰的,但在某个地方必须剪掉结,对吧?我错了吗?
我已经看到流被用作comonad的默认示例,但我不能完全确定它们是如何无限的,但不是。Haskell Streams(Comonadic):无限?
假设我们有数据的构造函数(from here)
data Stream a = a :> Stream a
我们如何最终完成从流?我们写在最后有没有定义?我知道这种语言是懒惰的,但在某个地方必须剪掉结,对吧?我错了吗?
流本身是无限的;您无法创建有限的流。比较Stream
和List
:
data List a = Empty | a : List a
data Stream a = a :> Stream a
您可以创建因为Empty
构造一个有限列表;有可能创建一个List
值,而不涉及另一个List
值。 A Stream
值,另一方面,可以只用通过使用创建另一个Stream
值。 任何时间模式匹配Stream
,你会得到一个值a
和另一个Stream
值。
“完成”一个流只是意味着你停止从它中提取值,而不是你达到流的“结束”。
实际上,这意味着你不能在内存中实例化一个完整的流;您只能按需构建它,通常通过调用函数在构造函数:>
上的模式匹配时生成流的其余部分。
虽然在指称上完全合理,但最后一段(关于“在记忆中实例化一个完整的流”)在操作上不正确 - 这正是打结给你的结果!例如,给定定义'ones = 1:> ones',流将由一个指向自身的单个“cons”单元表示(一旦thunk消失)。 –
一个更现实的场景是用户按下的按键流:你将它视为一个无限流,因为从来没有一个按键被认为是最后一个(现在忽略ctrl-D)。程序结束时发生终止,而不是流结束时终止。 –
@ AntalSpector-Zabusky可以很好地解答问题。另外,所有的流都是圆形的呢? –
如果你完成它不会是无限的,是吧? –