for-loop - For 循环构造转为函数式

标签 for-loop functional-programming scheme racket nested-loops

我目前正在学习 Racket 并想完成以下简单任务:构造一个包含所有元组的列表 (i,j) : Int * Int0 <= i < N0 <= j < M .

在 Python 中,我会立即知道如何通过使用 for 循环来解决这个问题:

# Not using any modules on purpose here
a = []
for i in range(5):
    for j in range(6):
        a.append((i,j))     

但是我在 Racket 中做这件事时遇到了麻烦。到目前为止,我已经找到了一个解决方案,它通过使用递归定义的函数来复制 for 循环方法,该函数为 a : Af : Int -> A -> A满足方程

for 0 a f = (f 0) a
for n a f = for (n-1) ( (f n) a ) f  

这导致应用程序链:for n a f = ( (f 0) ∘ ... ∘ (f n) )(a) . (f ∘ g 我的意思是 fg 的组合)。所以先f n适用于 a , 然后 f (n - 1)结果等等。

鉴于我基本上想做类似 ((f 0 0) ∘ (f 0 1) ∘ ... ∘ (f N M)) (a) 的事情,它可以拆分为:

 (((f 0 0) ... (f 0 M)) ∘ ... ∘ ((f N 0) ... (f N M))) (a)
= ((λz. for M z (f 0)) ∘ ... ∘ (λz. for M z (f N))) (a)
= for N a (λi z. for M z (f i))

然后转换为以下 Racket 代码:

(define (for n a f)   ;; (for n '() cons) = range(n) = (0 1 ... n-1)
    (if (< 0 n) 
        (for (- n 1) (f (- n 1) a) f) 
        a))
        
(define a '())
(define (append i j x) (cons (cons i j) x))

(for 5 a (λ(i x) 
       (for 6 x (λ(j y) 
              (append i j y)))))

答案产生了预期的结果,并且至少很好,因为很明显如何使用任意数量的附加循环来扩展此构造。

但我仍然想知道是否有更简洁的功能方法来做到这一点。

我对任何使用或不使用函数的答案都很满意,这些函数可能已经存在于某些库中,而我到目前为止只是错过了这些函数。

最佳答案

您可能正在寻找 for*/list :

(for*/list ([i (range 5)]
            [j (range 6)])
  (list i j))

另见 Racket 指南 Iterations and Comprehensions .

关于for-loop - For 循环构造转为函数式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71091980/

相关文章:

javascript - javascript 中的函数式编程 - add(a)(b)(c)

haskell - 等式推理的名称从何而来?

scheme - 模拟 scheme 在 common lisp 中定义

ios - 如何在 swift 中创建一个由类实例填充的数组?

c++ - 如何退出for循环内嵌套的if-else语句?(C/C++)

jquery - 如何使用一个 jQuery 函数更改两个独立元素内的文本?

inheritance - 可扩展的宏定义

debugging - 方案和Smalltalk

bash - 为什么 bash 在对 C 风格字符串的内容进行循环时忽略换行符?

Javascript For 循环被函数调用中断?