Good Luck! x Typed Scheme x Curried Typed Scheme

最近、「Typed Scheme」とやらが話題を呼んでいるようです(http://www.ccs.neu.edu/home/samth/typed-scheme/ 参照)。「Scheme」言語に型を付けて、「Haskell」言語らしくする手法です。そうすれば、バッグをより解消しやすくなるそうです。

面白そうだったので、試しに作ってみました。先ず、普通のPLT Scheme言語で「good-luck.ss」という、ユーザー名によって出力するメッセージを変える手続きを作りました:

;; good-luck.ss
;; PLT-Scheme-specific program to wish a person good luck
;; 
;; Copyright(C) October 20, 2008, at 13:42, 
;; by Benjamin L. Russell

#lang scheme

(define (good-luck name)
  (if (string=? name "Nobody")
      (printf "You are ~a." name)
      (good-luck-helper name "Good Luck")))

(define (good-luck-helper a b)
  (printf "~a, ~a!" a b))

上記のSchemeソースコードを実行するには、先ず、DrScheme(http://www.csg.is.titech.ac.jp/~kourai/lecture/drscheme/drscheme.htmlhttp://download.plt-scheme.org/ 参照)をダウンロード・インストールし、その後、例えば、

(good-luck "Benjamin")

と入力すればいいのです。そうすれば、

Benjamin, Good Luck!

と返ってきますし、また

(good-luck "Nobody")

と入れると、

You are Nobody.

と返ってきます。

これだけでは面白くないので、今度はこれを「good-luck-typed.ss」という「Typed Scheme」の手続きに翻訳してみました:

;; good-luck-typed.ss
;; Typed Scheme version of good-luck.ss program to wish a person good luck
;; 
;; Copyright(C) October 20, 2008, at 13:46, 
;; by Benjamin L. Russell

#lang typed-scheme

(: good-luck-typed (String -> Void))
(define (good-luck-typed name)
  (if (string=? name "Nobody")
      (printf "You are ~a." name)
      (good-luck-helper-typed name "Good Luck")))

(: good-luck-helper-typed (String String -> Void))
(define (good-luck-helper-typed a b)
  (printf "~a, ~a!" a b))

主な変更点は「#lang typed-scheme」が加わったところと、「(: good-luck-typed (String -> Void))」と「(: good-luck-helper-typed (String String -> Void))」が追加された点ですね。

「good-luck-typed」はString型のパラメーターを入力とし、何も返さない(つまり、「Void」を返す)。「good-luck-helper-typed」はString型のパラメーター二つを入力とし、同じく何も返さない(つまり、また「Void」を返す)。

さて、結果はどうでしょう?

> (good-luck-typed "Benjamin")
Benjamin, Good Luck!
> (good-luck-typed "Nobody")
You are Nobody.
> 

なるほど、結果は同じですね。

本来なら、ここでバグが発生した時の違いなどを説明したいところですが、時間がありませんので、これはまたの機会に致しましょう。

最後に、カリー化(http://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%AA%E3%83%BC%E5%8C%96 参照)が可能なのか、好奇心がありました。では:

;; good-luck-curried.ss
;; Curried Typed Scheme version of good-luck.ss program to wish a person good luck
;; 
;; Copyright(C) October 20, 2008, at 17:44, 
;; by Benjamin L. Russell

#lang typed-scheme

(: good-luck-curried (String -> Void))
(define (good-luck-curried name)
  (if (string=? name "Nobody")
      (printf "You are ~a." name)
      ((good-luck-helper-curried name) "Good Luck")))

(: good-luck-helper-curried (String -> (String -> Void)))
(define ((good-luck-helper-curried a) b)
  (printf "~a, ~a!" a b))

主な違いは、「(: good-luck-helper-curried (String -> (String -> Void)))」と「(define ((good-luck-helper-curried a) b)」のそれぞれの変更点です。なるほどです、確かにカリー化されているようです。それにしても、「(: good-luck-helper-curried (String -> (String -> Void)))」の括弧のつけ方が右よりであるのに対し、「(define ((good-luck-helper-curried a) b)」の括弧のつけ方が左よりである点が少し気になりますね。

それはさておき(また時間がないので、後程に致しましょう)、結果はどうでしょう?

> (good-luck-curried "Benjamin")
Benjamin, Good Luck!
> (good-luck-curried "Nobody")
You are Nobody.
> 

なるほど、また結果は同じですね。

詳細なお話はまた次回の機会に。

あくまで、アマチュア関数型プログラミング研究者ですから・・・・・・。