如何理解Clojure的lazy-seq [英] How to understand clojure's lazy-seq

查看:96
本文介绍了如何理解Clojure的lazy-seq的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解clojure的lazy-seq运算符,以及一般的惰性计算概念.我知道该概念背后的基本思想:表达式的求值被延迟,直到需要该值为止.

I'm trying to understand clojure's lazy-seq operator, and the concept of lazy evaluation in general. I know the basic idea behind the concept: Evaluation of an expression is delayed until the value is needed.

通常,这可以通过两种方式实现:

In general, this is achievable in two ways:

  • 在编译时使用宏或特殊形式;
  • 在运行时使用lambda函数

使用惰性评估技术,可以构造评估为已使用的无限数据结构.这些无限序列利用lambda,闭包和递归. Clojure中,这些无限数据结构是使用lazy-seqcons形式生成的.

With lazy evaluation techniques, it is possible to construct infinite data structures that are evaluated as consumed. These infinite sequences utilizes lambdas, closures and recursion. In clojure, these infinite data structures are generated using lazy-seq and cons forms.

我想了解lazy-seq是怎么做到的.我知道它实际上是一个宏.请考虑以下示例.

I want to understand how lazy-seq does it's magic. I know it is actually a macro. Consider the following example.

(defn rep [n]
  (lazy-seq (cons n (rep n))))

此处,rep函数返回类型为LazySeq的延迟求值序列,现在可以使用序列API对其进行转换和使用(从而求值).该API提供功能takemapfilterreduce.

Here, the rep function returns a lazily-evaluated sequence of type LazySeq, which now can be transformed and consumed (thus evaluated) using the sequence API. This API provides functions take, map, filter and reduce.

在展开的表格中,我们可以看到如何使用lambda存储单元格的配方而无需立即对其进行评估.

In the expanded form, we can see how lambda is utilized to store the recipe for the cell without evaluating it immediately.

(defn rep [n]
  (new clojure.lang.LazySeq (fn* [] (cons n (rep n))))) 

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆