问题描述
我想将十进制编码改为chruch编码吗?
(define (encode n)
(lambda(fn)(lambda(x) (funPower (fn n)x))))
我的代码有什么问题?谢谢。
解决方法
数据结构和硬件决定的教堂号比二进制数慢得多。
#lang racket
; church-number->n : procedure -> number
(define (church-number->n cn)
((cn (λ (x) (+ 1 x))) 0))
; n->church-number : number -> procedure
(define (n->church-number n)
(local [(define zero (λ (f) (λ (x) x)))
(define add-1
(lambda (n)
(lambda (f)
(lambda (x) (f ((n f) x))))))
(define (aux n cn)
(if (= 0 n)
cn
(aux (- n 1) (add-1 cn))))]
(aux n zero)))
;;; TEST
(church-number->n (n->church-number 101)) ; 101
(church-number->n (n->church-number (church-number->n (n->church-number 666)))) ; 666
; still slow than binary number
(church-number->n
(compose (n->church-number 100) (n->church-number 5))) ; 500
(define mult
(lambda (m)
(lambda (n)
(lambda (f)
(lambda (x)
((m (n f)) x))))))
(church-number->n ((mult (n->church-number 100)) (n->church-number 5))) ; 500
,
你写了
(define (encode n)
(lambda(fn)(lambda(x) (funPower (fn n)x))))
假设您已经定义了funPower
((funPower fn n) x) = (fn (fn ( ... (fn x) ... )))
;; \____n_times____/
(正如我们最近在这里看到的几个此类问题), 你的意思是
(define (encode n)
(lambda (fn)
(lambda (x) ((funPower fn n) x))))
即编码的n
是咖喱函数,期望fn
然后是x
,这样
(((encode n) fn) x) = ((funPower fn n) x)
= (fn (fn ( ... (fn x) ... )))
;; \____n_times____/
所以这只是适当的括号问题。
该定义可以通过调整效率来实现,例如
(define (encode n)
(lambda (fn)
((lambda (g)
(lambda (x) (g x)))
(funPower fn n))))
在接收(funPower fn n)
之前计算x
,而不是每次对每个新x
都进行一次计算,这肯定是浪费的;不言而喻等同于
(define (encode n)
(lambda (fn)
((lambda (g)
g)
(funPower fn n))))
,然后,进一步
(define (encode n)
(lambda (fn)
(funPower fn n)))
通过重复平方的乘幂运算,可以使 funPower
本身比n
项fn
的线性合成更有效率。