Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么';s相当于Clojure';球拍中的s迭代函数_Clojure_Functional Programming_Racket - Fatal编程技术网

什么';s相当于Clojure';球拍中的s迭代函数

什么';s相当于Clojure';球拍中的s迭代函数,clojure,functional-programming,racket,Clojure,Functional Programming,Racket,今天我在玩Racket,试图根据同一函数的多个应用程序生成一个不确定的数字序列 在Clojure中,我会为此使用迭代函数,但我不确定Racket中的等价物是什么。内置Racket过程中没有直接等价物,但我们可以使用实现类似功能的东西。试试这个: (define (stream-take m s) (if (zero? m) '() (cons (stream-first s) (stream-take (sub1 m) (stream-rest

今天我在玩Racket,试图根据同一函数的多个应用程序生成一个不确定的数字序列


在Clojure中,我会为此使用迭代函数,但我不确定Racket中的等价物是什么。

内置Racket过程中没有直接等价物,但我们可以使用实现类似功能的东西。试试这个:

(define (stream-take m s)
  (if (zero? m)
      '()
      (cons (stream-first s)
            (stream-take (sub1 m) (stream-rest s)))))

(define (iterate f x)
  (stream-cons x (iterate f (f x))))
例如,以下是Clojure在Racket中的示例:

(stream-take 5 (iterate add1 5))
=> '(5 6 7 8 9)

(stream-take 10 (iterate (curry + 2) 0))
=> '(0 2 4 6 8 10 12 14 16 18)

(define powers-of-two (iterate (curry * 2) 1))
(stream-ref powers-of-two 10)
=> 1024
(stream-take 10 powers-of-two)
=> '(1 2 4 8 16 32 64 128 256 512)

(define fib
  (stream-map first
              (iterate (lambda (pair)
                         (list (second pair)
                               (+ (first pair) (second pair))))
                       '(0 1))))
(stream-take 10 fib)
=> '(0 1 1 2 3 5 8 13 21 34)
(需要srfi/41)
)直接提供
流迭代

您可以使用Óscar的示例,在看到
iterate
的任何地方替换
stream iterate
,而无需定义自己的
iterate
。此外,可以使用
match lambda
模拟Clojure的参数分解:

(require srfi/41)
(define fib
  (stream-map first
              (stream-iterate (match-lambda
                                ((list a b)
                                 (list b (+ a b))))
                              '(0 1))))
(stream->list 10 fib)  ; => (0 1 1 2 3 5 8 13 21 34)

在大多数情况下,您可以将
iterate
替换为
for/fold

> (define (mult2 x) (* x 2))

> (for/fold ([x 1])   ; the initial value of x is 1
            ([i 8])   ; count i=0,...,7
   (mult2 x))         ; put x = (mult2 x)
256
for/fold
的优点是,您可以一次迭代更多变量:

(define (mult2 x) (* x 2))
(define (div2 x)  (/ x 2))

(for/fold ([x 1]        ; bind x to 1
           [y 1])       ; bind y to 1
          ([i 8])       ; i=0,...,7
  (values (mult2 x)     ; put x = (mult2 x)
          (div2  y)))   ; put y = (div2 y)
这将返回两个值:
256
1/256

收集元素很容易。下面是斐波那契的例子:

(for/fold ([fs '(1)]     ; list of fibonacci numbers generated so far
           [f1   1]      ; a fibonacci number
           [f2   1])     ; the following fibonacci number
          ([i   10])     ; i = 0,...,9
  (values (cons f2 fs)   ; cons the new fibonacci number to the list fs
          f2             ; put f1 = (the old) f2
          (+ f1 f2)))    ; put f2 = (the old) f1+f2
结果由三个值组成:

'(89 55 34 21 13 8 5 3 2 1 1)
89
144

基于soegaard使用渴望理解的想法,这里有一个嵌套序列中的
序列生成器(也可提供和使用):

由嵌套序列中的
生成的序列不终止,因此您需要将其与终止的序列或
:break
或类似终止条件配对。例如(使用Óscar答案中的两个
的幂):

下面是斐波那契序列的例子:

;; first ten Fibonacci numbers
(for/list ((_ (in-range 10))
           ((x y) (in-nest-sequence (lambda (a b) (values b (+ a b))) 0 1)))
  x)
; => (0 1 1 2 3 5 8 13 21 34)

;; first Fibonacci number above 10,000,000
(for/first (((x y) (in-nest-sequence (lambda (a b) (values b (+ a b))) 0 1))
            #:when (> x 10000000))
  x)
; => 14930352

另外-期望/fold
比stream更快。当然,热切的理解比streams更轻量级实际上,我应该在iterate序列生成器中编写一个
,可以直接与
一起用于理解。@ChrisJester-Young这是个好主意。我在iterate
中发布了我的
,作为一个新答案。我喜欢它的一点是,它可以处理多个值,而不需要让用户打包和解包(与Óscar的答案和我的初始答案不同)。事实上,我希望有朝一日它能成为Racket标准库的一部分…(我的代码是在“公共领域风格”CC0下发布的,可以自由使用,也可以不使用属性)。我迫不及待地想看看
定义序列语法
版本:-)看起来很棒,不过我会花一些时间来消化它。我是一个非常挑剔的n00b。@interstar在-*
实现中没有真正容易的方法来消化
;它们是使用一种特殊的领域特定语言编写的(无论是我使用的
make-do-sequence
,还是soegaard建议的
define-sequence-syntax
)。但是如果你喜欢学习新的东西,它肯定会达到这个目的!至于在iterate
中使用
,则更容易。对于单参数情况(上面的
(curry*2)
示例,顺便说一下,它与
(lambda(x)(*2x))
相同),这应该非常简单。双参数案例只是扩展了概念(以及您传入的函数)以使用两个参数和两个返回值。@soegaard我编写了
define sequence syntax
版本的第一部分。不过,我在这方面完全不在行,所以我欢迎你的任何批评!(实际上,我应该将此发布到CodeReview Stack Exchange,看看我得到了什么反馈。:/P)
;; first ten powers of 2
(for/list ((_ (in-range 10))
           (x (in-nest-sequence (curry * 2) 1)))
  x)
; => (1 2 4 8 16 32 64 128 256 512)

;; powers of 2 above 10,000 and below 1,000,000
(for/list ((x (in-nest-sequence (curry * 2) 1))
           #:when (> x 10000)
           #:break (> x 1000000))
  x)
; => (16384 32768 65536 131072 262144 524288)

;; first power of 2 above 10,000,000
(for/first ((x (in-nest-sequence (curry * 2) 1))
            #:when (> x 10000000))
  x)
; => 16777216
;; first ten Fibonacci numbers
(for/list ((_ (in-range 10))
           ((x y) (in-nest-sequence (lambda (a b) (values b (+ a b))) 0 1)))
  x)
; => (0 1 1 2 3 5 8 13 21 34)

;; first Fibonacci number above 10,000,000
(for/first (((x y) (in-nest-sequence (lambda (a b) (values b (+ a b))) 0 1))
            #:when (> x 10000000))
  x)
; => 14930352