LoginSignup
5
3

More than 5 years have passed since last update.

Scheme(Racket)の勉強日記 継続と継続渡し(1)

Last updated at Posted at 2018-11-07

はじめに

スキルアップに繋がればと思い、投稿を始めました。
自分の記録用でもありますので、少々読みづらいかと思います。
不慣れなため、どうかご容赦ください。

環境など

  • PC
    • Windows 7 SP1 64bit
    • Core-i3 3.30GHz
    • 4.00GB
  • DrRacket Ver.
    • 7.0

ソース

calc_cps.rkt (1)

;; 脱出継続用に定義
;; (and-not-number? x y)  ;=> boolean
;;
;; (and-not-number? 3 5)    ;=> #t
;; (and-not-number? "3" 5)  ;=> #f
;; (and-not-number? 3 '|5|)    ;=> #f
;; (and-not-number? '|3| "5")  ;=> #f
(define and-not-num?
  (lambda (x y)
    (if (and (not (number? x))
             (not (number? y)))
        #t #f)))


;; (calc/cps operator left-term right-term continuation)
;=> (continuation (operator left-term right-term))
;
;; (calc/cps + 3 5 displayln)
;=> 8
(define calc/cps
  (lambda (operator left-term r-term continuation)
    (continuation
     (call/cc (lambda (exit)
                (if (and-not-num? left-term right-term)
                    (exit (error "数値ではない値です"))
                    (operator x y)))))))

;; 加算
(define add/cps
  (lambda (x y cont)
    (calc/cps + x y cont)))

;; 減算
(define sub/cps
  (lambda (x y cont)
    (calc/cps - x y cont)))

;; 乗算
(define mul/cps
  (lambda (x y cont)
    (calc/cps * x y cont)))

;; 除算
(define div/cps
  (lambda (x y cont)
    (calc/cps / x y cont)))
calc_cps.rkt (2)

;; 三角形の面積を求める。
;; (/ 2 (* 底辺 高さ))
;;
;; 底辺 10, 高さ 3
(mul/cps 10 3
         ; 10 に 3 をかけて
         (lambda (val)
           (div/cps val 2
                    ; 2 で割ったら
                    displayln))) ; 結果を表示する。(改行あり)
;=> 15

;; コメント無し
(mul/cps 10 3
         (lambda (val)
           (div/cps val 2
                    displayln)))
;=> 15


;; 台形の面積を求める。
;; (/ (* (+ 上底 下底) 高さ) 2)
;;
;; 上底 5, 下底 7, 高さ 10
(add/cps 5 7
         ; 5 と 7 を足して、
         (lambda (val)
           (mul/cps val 10
                    ; 10 をかけて、    
                    (lambda (val)
                      ; 2 で割ったら、
                      (div/cps val 2            
                               ; 結果を表示する。(改行あり)
                               displayln)))))
;=> 60

;; コメント無し
(add/cps 5 7
         (lambda (val)
           (mul/cps val 10       
                    (lambda (val)
                      (div/cps val 2
                               displayln)))))
;=> 60


;; 三角錐の体積を求める。
;; (/ (* (* (* 半径 半径) 3.14) 高さ) 3)
;;
;; 半径 10, 高さ 30
(mul/cps 10 10
         ; 10 に 10 をかけて、
         (lambda (val)
           (mul/cps val 3.14
                    ; 3.14 をかけて、
                    (lambda (val)
                      (mul/cps val 30
                               ; 30 をかけて、
                               (lambda (val)
                                 ; 3 で割ったら、
                                 (div/cps val 3
                                          ; 結果を表示する。(改行あり)
                                          displayln)))))))
;=> 3140  ※小数点以下、切り捨て

;; コメント無し
(mul/cps 10 10
         (lambda (val)
           (mul/cps val 3.14
                    (lambda (val)
                      (mul/cps val 30
                               (lambda (val)
                                 (div/cps val 3
                                          displayln)))))))
;=> 3140  ※小数点以下、切り捨て

まとめ

冗長になりがちですが、流れをつかみやすくなった感じがします。
マクロとかを使えばもっとスッキリするのか、今後の課題です。

最後まで読んでいただきありがとうございました。

5
3
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3