如何返回教堂号码

问题描述

我想将十进制编码改为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本身比nfn的线性合成更有效率。

>