【问题标题】:scheme function to call a procedure n times调用过程 n 次的方案函数
【发布时间】:2014-02-15 03:05:00
【问题描述】:

scheme 是否有一个函数可以调用一个函数 n 次。我不想要 map/for-each 因为该函数没有任何参数。类似这样的东西:-

(define (call-n-times proc n)
        (if (= 0 n)
            '()
            (cons (proc) (call-n-times proc (- n 1)))))

(call-n-times read 10)

【问题讨论】:

    标签: scheme guile


    【解决方案1】:

    SRFI 1 有一个 list-tabulate 函数,它可以通过调用给定函数构建一个列表,参数为 0 到 (- n 1)。但是不保证执行顺序(其实很多实现都是从(- n 1)开始往下走),所以用read调用并不理想。

    在 Racket 中,您可以这样做:

    (for/list ((i 10))
      (read))
    

    调用read 10 次并收集每个结果;它会从左到右进行。但是由于您将问题标记为 Guile,我们需要做一些不同的事情。

    幸运的是,Guile 有 SRFI 42,它使您能够:

    (list-ec (: i 10)
      (read))
    

    【讨论】:

    • 酷。我现在将使用我自己的一个。我想知道他们为什么把它从标准中删除。很高兴知道这不是太明显:)
    • @Himanshu Scheme,至少在早期版本中,是一种非常简单的语言。事实上,这是一个非常容易编写的实用程序,这是将其排除在语言之外的一个很好的理由。 “只有三行,写起来容易吗?我们不需要放在spec里面。” :)
    • @JoshuaTaylor 是的,听起来很合理。我发现 Scheme 的极简性是最吸引人的特性。
    【解决方案2】:

    手动实现tail-recursion modulo cons 优化,用 O(1) 额外空间构建结果列表:

    (define (iterate0-n proc n)   ; iterate a 0-arguments procedure n times
      (let ((res (list 1)))       ; return a list of results in order
        (let loop ((i n) (p res))
          (if (< i 1)
            (cdr res)
            (begin
              (set-cdr! p (list (proc)))
              (loop (- i 1) (cdr p)))))))
    

    此技术首先 (?) 在 Friedman and Wise's TR19 中描述。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 2020-01-18
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-19
      相关资源
      最近更新 更多