Scheme 球拍折叠的展开形式

Scheme 球拍折叠的展开形式,scheme,racket,Scheme,Racket,示例来自: 球拍输出: 5 193/196 5 193/196 在这种情况下,foldl和foldr的完整(扩展)形式是什么?这不是以下几点: > (/ (/ (/ (/ (/ 7 34) 56) 12) 4) 23) 1/300288 编辑:我已经修改了上面的问题,因为在另一个问题中解释了折叠球拍vs Haskell的实现 编辑:如果我清楚地理解了答案,那么可以使用“线程”模块非常清楚地显示扩展的表单,其中语句按执行顺序显示(u表示前一个语句的输出): 福尔德尔: (require

示例来自:

球拍输出:

5 193/196
5 193/196
在这种情况下,foldl和foldr的完整(扩展)形式是什么?这不是以下几点:

> (/ (/ (/ (/ (/ 7 34) 56) 12) 4) 23)
1/300288
编辑:我已经修改了上面的问题,因为在另一个问题中解释了折叠球拍vs Haskell的实现

编辑:如果我清楚地理解了答案,那么可以使用“线程”模块非常清楚地显示扩展的表单,其中语句按执行顺序显示(u表示前一个语句的输出):

福尔德尔:

(require threading)
; expanded form of (foldl / 7 (list 34 56 12 4 23))
; FROM LEFT TO RIGHT: 
(~> 7
    (/ 34 _)
    (/ 56 _)
    (/ 12 _)
    (/ 4  _)
    (/ 23 _) )
福尔德:

; expanded form of (foldr / 7 (list 34 56 12 4 23))
; FROM RIGHT TO LEFT: 
(~> 7
    (/ 23 _)
    (/ 4  _)
    (/ 12 _)
    (/ 56 _)
    (/ 34 _) )
两种情况下的输出相同:

5 193/196
5 193/196
它在以下示例中给出了正确的答案(foldl和foldr的答案不同):

; FROM LEFT TO RIGHT:
(foldl - 0 '(1 2 3 4))
(~> 0
    (- 1 _)  ; 1-0=1
    (- 2 _)  ; 2-1=1
    (- 3 _)  ; 3-1=2
    (- 4 _)) ; 4-2=2

; FROM RIGHT TO LEFT: 
(foldr - 0 '(1 2 3 4))
(~> 0
    (- 4 _)  ; 4-0=4
    (- 3 _)  ; 3-4=-1
    (- 2 _)  ; 2-(-1)=3
    (- 1 _)) ; 1-3=-2
输出:

2
2
-2
-2
在共同语言中,似乎:

The sent function takes 2 arguments, 

the first argument is from the list, one after the other 
(left to right or right to left depending on foldl and foldr), 

the second argument is init first and 
then the output of previous calculation.

哈斯克尔的
foldr
foldl
并不完全等同于Racket的。另外,
div
是整数除法,所以你应该在Racket中使用商。但即便如此

(foldr quotient 7 (list 34 56 12 4 23)) => 8
(foldl quotient 7 (list 34 56 12 4 23)) => quotient: undefined for 0
您可以仔细阅读有关foldl和foldr工作原理的文档,但我想参考以下文档:

所以它变成了

(quotient 34 (quotient 56 (quotient 12 (quotient 4 (quotient 23 7)))))
(quotient 23 (quotient 4 (quotient 12 (quotient 56 (quotient 34 7)))))

哈斯克尔的
foldr
foldl
并不完全等同于Racket的。另外,
div
是整数除法,所以你应该在Racket中使用商。但即便如此

(foldr quotient 7 (list 34 56 12 4 23)) => 8
(foldl quotient 7 (list 34 56 12 4 23)) => quotient: undefined for 0
您可以仔细阅读有关foldl和foldr工作原理的文档,但我想参考以下文档:

所以它变成了

(quotient 34 (quotient 56 (quotient 12 (quotient 4 (quotient 23 7)))))
(quotient 23 (quotient 4 (quotient 12 (quotient 56 (quotient 34 7)))))

在DrRacket中,在
foldl
上按鼠标右键,然后在提供列表中选择“打开定义文件”,再次右键单击并选择“跳转到下一个绑定事件”。您将看到:

(define foldl
  (case-lambda
    [(f init l)
     (check-fold 'foldl f init l null)
     (let loop ([init init] [l l])
       (if (null? l) init (loop (f (car l) init) (cdr l))))]
    [(f init l . ls)
     (check-fold 'foldl f init l ls)
     (let loop ([init init] [ls (cons l ls)])
       (if (pair? (car ls)) ; `check-fold' ensures all lists have equal length
           (loop (apply f (mapadd car ls init)) (map cdr ls))
           init))]))
但是,因为您只有一个列表,所以它是case lambda中的第一个术语,它是当前的,第一行检查参数并抛出异常。您可以将其简化为:

(define (foldl f init l)
  (let loop ([init init] [l l])
    (if (null? l)
        init
        (loop (f (car l) init) (cdr l))))
使用替换规则:

(foldl / 7 '(34 56 12 4 23))                                  ;==>
(loop 7 '(34 56 12 4 23))                                     ;==>
(loop (/ (car '(34 56 12 4 23)) 7) (cdr '(34 56 12 4 23)))    ;==>
(loop (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7)) (cdr '(56 12 4 23)))    ;==>
(loop (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7))) (cdr '(12 4 23)))    ;==>
(loop (/ (car '(4 23)) (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7)))) (cdr '(4 23)))    ;==>
(loop (/ (car '(23)) (/ (car '(4 23)) (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7))))) (cdr '(23)))    ;==>
(/ (car '(23)) (/ (car '(4 23)) (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7)))))    ;==>
(/ 23 (/ 4 (/ 12 (/ 56 (/ 34 7)))))    ;==>
5 193/196
我将把
foldr
作为练习

关于褶皱和标准

折叠在
#中!球拍
是特定于球拍的。在Scheme中,更准确地说是
#!r6rs
您有
左折
右折
,与
不同!racket
参数从左到右的顺序发生变化,使其更类似于*新的Haskell版本


SRFI-1列表库使用名称
fold
foldr
,并期望两者的参数顺序相同,就像
#!球拍
。SRFI-1还支持不同长度的列表,并在最短的列表中停止,因此它是具有最多功能的列表。SRFI-1可以包含在两个
#中!球拍
带有
(需要srfi/1)
#!r6rs
<代码>(导入(rnrs:1))

在DrRacket中,在
foldl
上按鼠标右键,然后在提供列表中选择“打开定义文件”,再次右键单击并选择“跳到下一个绑定事件”。您将看到:

(define foldl
  (case-lambda
    [(f init l)
     (check-fold 'foldl f init l null)
     (let loop ([init init] [l l])
       (if (null? l) init (loop (f (car l) init) (cdr l))))]
    [(f init l . ls)
     (check-fold 'foldl f init l ls)
     (let loop ([init init] [ls (cons l ls)])
       (if (pair? (car ls)) ; `check-fold' ensures all lists have equal length
           (loop (apply f (mapadd car ls init)) (map cdr ls))
           init))]))
但是,因为您只有一个列表,所以它是case lambda中的第一个术语,它是当前的,第一行检查参数并抛出异常。您可以将其简化为:

(define (foldl f init l)
  (let loop ([init init] [l l])
    (if (null? l)
        init
        (loop (f (car l) init) (cdr l))))
使用替换规则:

(foldl / 7 '(34 56 12 4 23))                                  ;==>
(loop 7 '(34 56 12 4 23))                                     ;==>
(loop (/ (car '(34 56 12 4 23)) 7) (cdr '(34 56 12 4 23)))    ;==>
(loop (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7)) (cdr '(56 12 4 23)))    ;==>
(loop (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7))) (cdr '(12 4 23)))    ;==>
(loop (/ (car '(4 23)) (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7)))) (cdr '(4 23)))    ;==>
(loop (/ (car '(23)) (/ (car '(4 23)) (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7))))) (cdr '(23)))    ;==>
(/ (car '(23)) (/ (car '(4 23)) (/ (car '(12 4 23)) (/ (car '(56 12 4 23)) (/ (car '(34 56 12 4 23)) 7)))))    ;==>
(/ 23 (/ 4 (/ 12 (/ 56 (/ 34 7)))))    ;==>
5 193/196
我将把
foldr
作为练习

关于褶皱和标准

折叠在
#中!球拍
是特定于球拍的。在Scheme中,更准确地说是
#!r6rs
您有
左折
右折
,与
不同!racket
参数从左到右的顺序发生变化,使其更类似于*新的Haskell版本


SRFI-1列表库使用名称
fold
foldr
,并期望两者的参数顺序相同,就像
#!球拍
。SRFI-1还支持不同长度的列表,并在最短的列表中停止,因此它是具有最多功能的列表。SRFI-1可以包含在两个
#中!球拍
带有
(需要srfi/1)
#!r6rs
<代码>(导入(rnrs:1))

可能重复的我已经修改了我上面的问题。可能重复的我已经修改了我上面的问题。我想你第一句话中的一个“敲诈”应该是其他东西。我想你第一句话中的一个“敲诈”应该是其他东西。