pyてょnの reduse は accumulate の代わりに使えるんじゃないだろうか、と思ったり思わなかったりした、という話。総和とか階乗はこう書ける。

# 1-10の総和
reduce(lambda x, y: x+y, ((i for i in range(1, 11))), 0)
# 10の階乗
reduce(lambda x, y: x*y, ((i for i in range(1, 11))), 1)

cont-frac は accumulate を使ってこう書ける

(define (cont-frac n d k)
  (accumulate
   (lambda (x y) (/ (n x) (+ (d x) y)))
   1
   (lambda (x) x)
   1
   (lambda (x) (+ x 1))
   (- k 1)))

ってことはこう書けるんじゃないの?

def cont_frac(n, d, k):
  return reduce(lambda r, i: n(i)/(d(i)+r), ((i for i in range(1, k))), 1)

……と思ったけど、後ろからおさえる必要があるので気分的にはこっちに近い気が。

(define (cont-frac2 n d k)
  (define (iter i r)
    (if (< i 1)
        r
        (iter (- i 1)
              (/ (n a) (+ (d a) r)))))
  (iter k 1))

というわけで、こうする。

def cont_frac(n, d, k):
  return reduce(lambda r, i: n(i)/(d(i)+r), ((i for i in range(k-1, 0, -1))), 1)

もしくはこんな感じ。

def cont_frac2(n, d, k):
  return reduce(lambda r, i: i[0]/(i[1]+r), (((n(i), d(i)) for i in range(k-1, 0, -1))), 1)

ジェネレータじゃなくてリストでもいいけど。

def cont_frac2(n, d, k):
  return reduce(lambda r, i: i[0]/(i[1]+r), [(n(i), d(i)) for i in range(k-1, 0, -1)], 1)

そして e と tangent を求めるアレはこうなる。pyてょnの lambda には式1つしか書けないらしいので小細工をする。

def e(k):
  return 2 + cont_frac(lambda i: 1.0, lambda i: i%3==2 and i-i/3 or 1, k)

def tan(x, k):
  return cont_frac(lambda i: i==1 and x or -x**2, lambda i: 2*i-1, k)

結論:なんか微妙に違う。