次へ 前へ 目次へ 佐々木将人の個人ページへ

4 Erlangにおけるデータ型

 Erlangのデータには「型」があり,後で述べますがErlangの基本原理である「パターンマッチ」の際,型が違うと一致しない=マッチしないことになります。ただ,型のチェックは,プログラムの実行時に行うのであって,コンパイル時やその他プログラム実行前に行うのではない点がCやJavaと異なる点です。
(なお,データ型の一覧は,「Erlangのデータ型・型判別関数・型変換関数」のとおり)

整数(integer)

 文字どおり整数です。
 2~36の任意の整数に#が続いたものが前に置かれていると,基数を表します。たとえば8#だと8進整数,16#だと16進整数です。何もなければ10進整数です。
 ちなみにシェルで10進以外の整数を入れて . を入力すると,10進整数の値が返ります。
 整数と次に述べる浮動小数点数は算術演算(+ - * / 等)の対象です。もっとも整数にのみ適用される算術演算として,割り算の時の答の整数部(商)を求めるのが div ,いわゆる余りを求める rem があります。(7 div 3 . が2,7 rem 3 . が1)

浮動小数点数(float)

 いわゆる実数です。小数点付の数で,小数点以下の桁数が固定されていないものです。ちなみに小数点以下の数値が0であっても,例えば5.0と表記します。これを5と表記するとこれは浮動小数点数ではなく整数ということになります。(この点,数学の世界だと実数は整数を含むのですが,計算機の世界だと整数と浮動小数点数は型が違うとして扱われます。)
 ちなみに……整数と浮動小数点数をあわせて数値型とも言います。整数と浮動小数点数は型は違うのですが,算術演算においては,等しく5(もしくは5.0)として扱われ,普通に演算が可能となっています。

アトム(atom)

 atomの定義は若干複雑です。
 まず「'」(シングルクォート)で囲まれたものはアトムです。
 またシングルクォートで囲まれていなくても,英小文字もしくは英小文字から始まりその後に英数字,「@」,「_」が続くものはやはりアトムです。
 アトムは見たままを定数として保持しており,これを変更することはできません。
 またアトムを構成する文字列を分解したり,結合したりすることはできません。
 あまり問題にはなりませんが,Erlangのアトムの個数には制限があります。その制限は一定の操作で変更することができますが,Lispのように「記憶領域の許す限り無制限」というわけにはいきません。したがって,プログラムの中でアトムを新たに生成するような使い方には注意が必要です。

リスト(list)

 Erlangにおけるリストについては「3 Erlangにおけるリスト」で説明したとおりです。
 Lispにはない,Erlangのリストの特徴として,「リスト内包表記」という記法が許されるということがあります。
 リスト内包表記の単純な例は,[ N * 2 || N <- [1,2,3,4] ]. です。これは [2,4,6,8]というリストを表します。[1,2,3,4]というリストのそれぞれの要素をNに順次あてはめ,それぞれN*2を計算して,そのリストを生成します。
 一般的には [ 式 || 生成式1 , 生成式2 , …… , 生成式N
           条件1 , 条件2 , …… , 条件M ]
という形を取ります。ただ詳細な説明は他のErlangの解説書に任せます。
※生成式は「N <- [1,2,3,4]」のように「パターン <- リスト」の形式

 その他に,LispにないErlangのリストの特徴としては,++ や -- でリストの要素の足し算,引き算ができるというものがあります。
 例えば [1,3]++[2,4]は[1,2,3,4]になります。
 ++や--が複数ある時は,右にある++や--を先に処理します。
 例えば[1,2,3,4,5]--[1,2,3]--[3]は右の--の前後にある[1,2,3]--[3]を先に処理して,その結果の[1,2]を求め,[1,2,3,4,5]--[1,2]として答が[3,4,5]となります。

文字列を表すリスト……本質は普通のリスト(list)

 便宜上「文字列を表すリスト」とはしましたが,文字列を表すリストという型が別個あるわけではなく,他のリストと同じリストという型です。文字列が独自の扱いをされず,他のデータ型と同じ扱いになるものとして代表的なものにC言語があります。C言語も文字列という独立の型はなく,その本質は配列であり,ポインターなわけです。
 仮にリストの中の各要素が全て文字を表す数値であった場合,その数値のリストを返すのではなく,「""」でくくられた文字列を返します。一方1個でも文字を表さない数値であった場合には,変換できるものも変換しないで数値のリストを返します。

タプル(tuple)

 複数の要素を「,」で区切り,「{}」で囲んだものです。例えば {2,3} はタプルです。タプルの要素もまた制限がありませんし,タプルの中にタプルがあってもかまいません。
 パターンマッチというのは,Erlangの中心とも言える概念ですが,詳細はあとで説明します。とりあえずは,「パターンが一致する」くらいのざっくりした理解でかまいません。
 タプルについてパターンマッチが成功するためには,タプルの中の要素の数が一致していなければなりません。要素の数が違うと,それだけでパターンマッチは失敗ということになります。一方リストでは,リストの中の要素の数が一致しなくても,headとtail(carとcdr)でパターンマッチが成功してしまいます。
 Lispに慣れてしまうとリストがあれば十分で,別途タプルという型を持つ必要性を感じないのですが,タプルにすると要素数が違うことでパターンマッチを失敗させられるため,その方が話が早い場合があるのは理解できます。

変数

 変数自体は型ではありませんが,上で述べたアトムの定義が若干複雑になっているのは,変数の定義に原因がありますので,便宜上ここで扱うことにします。
 変数は英大文字で始まるものと,「_」(アンダースコア)で始まるものとがあります。もっとも「_」で始まる変数は一時的に使用して使い捨てるための変数に使うのがErlang界でのお約束ではあります。
 変数は最初の段階では値が束縛されていません。そして一旦値が束縛された変数は,その内容を変えることができません。これがErlang最大の特徴であり,並列処理を容易にしている要因にもなっているのです。

データ型を調べる関数

 Erlangでは,データ型のチェックを厳格に行い,データ型が違うとエラーを出します。そこで,データ型を調べる関数が必要となります。
 以下では原則としてtrueを返す場合を述べています。trueを返さない場合はfalseを返します。
(なお,データ型を調べる関数の一覧は,「Erlangのデータ型・型判別関数・型変換関数」のとおり)
is_number(X)
Xが数値型(number)であればtrue。
is_integer(X)
Xが整数型(integer)であればtrue。
is_float(X)
Xが浮動小数型(float)であればtrue。
is_atom(X)
Xがアトムであればtrue。
is_tuple(X)
Xがタプルであればtrue。
is_list(X)
Xがリストであればtrue。
type_of(X)
Xのデータ型をinteger,float,atom,tuple,listの要領で返す。

データ型を変換する関数

 データ型が異なるままだとパターンマッチが利かないので,データ型を変換する関数があります。基本的には「(変換前のデータ型)_to_(変換後のデータ型)」という名前になっていますが,全てのデータ型について関数が用意されているわけではありません。
(なお,データ型を変換する関数の一覧は,「Erlangのデータ型・型判別関数・型変換関数」のとおり)
integer_to_list(X),integer_to_list(X,Y),float_to_list(X),atom_to_list(X),tuple_to_list(X)
list_to_tuple(X)
list_to_integer(X,Y)
list_to_float(X)

(2023.5.19. 初版)
(2023.6.9. 改訂)

次へ 前へ 目次へ 佐々木将人の個人ページへ