clojure中惰性序列的使用
我想知道lazy seq返回的是有限列表还是无限列表。有一个例子,clojure中惰性序列的使用,clojure,lazy-sequences,Clojure,Lazy Sequences,我想知道lazy seq返回的是有限列表还是无限列表。有一个例子, (defn integers [n] (cons n (lazy-seq (integers (inc n))))) 当我像你一样跑的时候 (first integers 10) 或 结果是10和(10 11 12 13 14) . 然而,当我跑的时候 (integers 10) 进程无法打印任何内容,无法继续。有谁能告诉我为什么和laza seq的用法吗。非常感谢你 它不会返回任何内容,因为整数函数创建了一个无限
(defn integers [n]
(cons n (lazy-seq (integers (inc n)))))
当我像你一样跑的时候
(first integers 10)
或
结果是10和(10 11 12 13 14)
. 然而,当我跑的时候
(integers 10)
进程无法打印任何内容,无法继续。有谁能告诉我为什么和laza seq的用法吗。非常感谢你 它不会返回任何内容,因为整数函数创建了一个无限循环
(defn integers [n]
(do (prn n)
(cons n (lazy-seq (integers (inc n))))))
用
(integers 10)
调用它,你会看到它一直在计数。它没有返回任何东西,因为你的integers函数创建了一个无限循环
(defn integers [n]
(do (prn n)
(cons n (lazy-seq (integers (inc n))))))
用
(整数10)
调用它,你会看到它永远在计数。当你试图打印一个无限制的惰性序列时,它将被完全实现,除非你限制。当你试图打印一个无限制的惰性序列时,它将被完全实现,除非你限制。当你说你正在运行时
(integers 10)
你真正做的是这样的:
user> (integers 10)
换句话说,您正在REPL(read-eval-print循环)中评估该表单
“读取”步骤将从字符串(整数10)
转换为列表(整数10)
。很简单
“eval”步骤将在周围上下文中查找整数
,查看它是否绑定到函数,并使用参数10
计算该函数:
(cons 10 (lazy-seq (integers (inc 10))))
由于一个lazy seq
直到需要时才被实现,因此简单地计算这个表单就会得到一个clojure.lang.Cons
对象,其第一个元素是10
,而其rest
元素是一个尚未实现的clojure.lang.LazySeq
您可以通过一个简单的def
(无无限挂起)来验证这一点:
在最后一个“打印”步骤中,Clojure基本上尝试将刚刚计算的表单结果转换为字符串,然后将该字符串打印到控制台。对于有限序列,这很容易。它只是不断从序列中提取项目,直到没有剩余的项目为止,将每个项目转换为字符串,用空格分隔,在末尾插入一些括号,然后瞧:
user> (take 5 (integers 10))
;=> (10 11 12 13 14)
但是,正如您定义的整数
,在某个点上不会有任何项目剩余(至少在您得到整数溢出之前是这样,但这可以通过使用inc'
而不是仅使用inc
进行补救)。因此Clojure能够很好地读取和评估您的输入,但它无法打印无限结果的所有项目。当您说您正在运行时
(integers 10)
你真正做的是这样的:
user> (integers 10)
换句话说,您正在REPL(read-eval-print循环)中评估该表单
“读取”步骤将从字符串(整数10)
转换为列表(整数10)
。很简单
“eval”步骤将在周围上下文中查找整数
,查看它是否绑定到函数,并使用参数10
计算该函数:
(cons 10 (lazy-seq (integers (inc 10))))
由于一个lazy seq
直到需要时才被实现,因此简单地计算这个表单就会得到一个clojure.lang.Cons
对象,其第一个元素是10
,而其rest
元素是一个尚未实现的clojure.lang.LazySeq
您可以通过一个简单的def
(无无限挂起)来验证这一点:
在最后一个“打印”步骤中,Clojure基本上尝试将刚刚计算的表单结果转换为字符串,然后将该字符串打印到控制台。对于有限序列,这很容易。它只是不断从序列中提取项目,直到没有剩余的项目为止,将每个项目转换为字符串,用空格分隔,在末尾插入一些括号,然后瞧:
user> (take 5 (integers 10))
;=> (10 11 12 13 14)
但是,正如您定义的整数
,在某个点上不会有任何项目剩余(至少在您得到整数溢出之前是这样,但这可以通过使用inc'
而不是仅使用inc
进行补救)。因此Clojure能够很好地读取和计算您的输入,但它无法打印无限结果的所有项。惰性seq
宏从不构造有限或无限的列表。它构造了一个clojure.lang.LazySeq
对象。这是一个标称序列,它封装了一个无参数的函数(通常称为thunk),调用时该函数的计算结果为实际序列;但是直到必须调用它时才调用它,这就是该机制的目的:延迟对实际序列的评估
因此,如果您从未意识到它们,您可以将无休止的序列作为已评估的LazySeq
对象传递。您在REPL的评估调用了实现,这是一个无休止的过程 lazy seq
宏从不构造有限或无限的列表。它构造了一个clojure.lang.LazySeq
对象。这是一个标称序列,它封装了一个无参数的函数(通常称为thunk),调用时该函数的计算结果为实际序列;但是直到必须调用它时才调用它,这就是该机制的目的:延迟对实际序列的评估
因此,如果您从未意识到它们,您可以将无休止的序列作为已评估的LazySeq
对象传递。您在REPL的评估调用了实现,这是一个无休止的过程