(はじめよう Scheme 5)

組み込み型


ここではSchemeの型について記述する。R7RS Schemeには組み込み型(規格で定義されている型)とユーザ定義型(define-record-typeで定義する型)の2種類がある。また、述語手続きが#tを返すものはその型に属すると考える。例:number?#tを返す値が数値である。

真偽値型


数値型はboolean?#tを返す値である。Schemeでは#t及び#fが真偽値型の値になる。

数値型


数値型はnumber?#tを返す値である。Schemeで数値は数値塔(numeric tower)と呼ばれる以下のような階層構造になっている。
数値   (number?)
複素数 (complex?)
実数   (real?)
有理数 (rational?)
整数   (integer?)
数値塔は上位にあるものは下位を含む。例えば、5は整数であるので、有理数でもあり、実数でもあり、複素数でもある。

数値の例
1234
#x1234  ;; -> 4660 (#xは16進数を表す)
#b0101  ;; -> 5    (#bは2進数を表す)
#o1234  ;; -> 668  (#oは8進数を表す)
1+1i    ;; -> 複素数1+1i
Schemeの数値はさらに正確数、非正確数という概念を持つ。正確数とは計算結果に誤差が生じない数値で、非正確数とは誤差が生じる数値のことである。ちなみに非正確数は不動少数点数のことだという理解でよい。数値の表記は上記の他に正確、非正確を表すためのものもあるが、ここでは割愛する(都度記載することとする)。

誤差が出る計算の例
(- 123.456 123.444)
;; -> 0.012に近い数値
;; 処理系によっては誤差はでないかもしれない
なお、非正確な整数(例:1.0)というものも存在しえるので、有理数以下の数値塔は正確数であるという理解は間違いである。

文字型


文字型とは文字を表す型である。char?手続きが#tを返す値をSchemeでは文字と呼ぶ。

文字の例
#\A
(integer->char 65) ;; -> #\A
R7RSでは文字は少なくともASCIIの範囲をサポートしていることが保障されている。Unicodeのサポートは処理系依存になる。

文字列型


文字列型はその名の通り文字列を現す型である。string?手続きが#t返す値をSchemeでは文字列と呼ぶ。文字列はリテラル文字列とそうでな文字列の2種類があり、前者を破壊的に変更することはR7RSではエラーとされている。
"Hello!!"                    ;; リテラル文字列、ダブルクオートで囲む
(string #\H #\e #\l #\l #\o) ;; 非リテラル文字列。生成手続きはいくつかある

;; これはエラー(処理系によっては受け付ける)
(string-set! "Hello" 0 #\h)

;; これはOK
(let ((s (string #\H #\e #\l #\l #\o)))
  (string-set! s 0 #\h)
  s)
;; "hello"
R7RSでは文字列はASCIIからNULL文字を除いた範囲の文字を持つことができることが保障されている*1。Unicodeのサポートは処理系依存になる。

シンボル型


シンボル型はシンボルを表す型である。symbol?#tを返す値をSchemeではシンボルと呼ぶ。

シンボルの例
abc
|ab cde|
|H\x65;llo|
+soup+
上記は全てシンボルである。Schemeでシンボルを直接書くと評価され、そのシンボルに何の値も束縛されていなければエラーとなる。シンボルをプログラムないで使う場合にはquoteで囲む必要がある。
(quote a) ;; -> a
'a        ;; -> a ('はquoteの略表記)

手続き型


手続き型は手続きを表す型である。procedure?#tを返す値をSchemeでは手続きと呼ぶ。
手続きはlambda構文によって作られる*2
(procedure? (lambda (o) o)) ;; -> #t

バイトベクタ型


バイトベクタ型はバイトベクタを表す型である。bytevector?#tを返す値をSchemeではバイトベクタと呼ぶ。バイトベクタとは名前が示すとおり0 ≦ x ≦ 255までの数値のみを要素に持つ配列のことである。なぜオクテットベクタでないのかというのは筆者は知らない。
バイトベクタの例
#u8(1 2 3) ;; -> #u8(1 2 3)

*1: 文字と同一範囲がサポートされていた方が美しいじゃないかという意見をWG1に言ってはみたが却下された。
*2: 処理系によってはそれ以外の方法もあるが(例:総称関数)、ここでは扱わない。

No comments:

Post a Comment