CodeZine(コードジン)

特集ページ一覧

新たな関数型言語「F#」

C#プログラマのためのF#入門(1)

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2009/09/04 14:00

目次

F#の構文基本

 準備も完了したので、さっそくF#を使ってみましょう。基本的な構文から紹介します。

letバインド(束縛)

 letはF#において、最も重要なキーワードの1つです。使い方は難しくないと思いますが、例を用いて紹介します。

letと識別子のバインド(束縛)

 let は識別子に値を割り当てるもしくは、関連付けます。これをバインド(束縛)と言います。F#の束縛は、C#における「変数の宣言」とは若干異なります。F#における束縛で、いったん定義された識別子は変化することがありません。

[構文]let:値のバインド(束縛)
let 識別子またはパターン[: 型] =
   式(expression)
本文式(body-expression)

 では、実際にインタープリタを起動して、下記のコマンドを一つずつ実行してみましょう。

[リスト3]aにint型の1をバインド
> let a = 1 ;;

 ▼

val a : int = 1 //aにint型の1がバインドされたことをインタープリターが表示
[リスト4]cにchar型のaをバインド
> let c = 'a' ;;

 ▼

val c : char = 'a'

 式を識別子から離して改行して記述する場合には、インデントを使用する必要があります。改行された本文式(body-expression)は、let式のトップと同じ位置にインデントして記述を開始する必要があります(この設定は変更可能ですが、詳細は次回の連載にて紹介予定です)。本文式(body-expression)とは、その識別子が使用される式のことです。

[リスト5]body-expressionの例
> let testVal =
    //通常の式:expression(半角スペース4つ分のインデント)
    let x, y = (1, 2)
    //識別子xとyが使用される式(body-expression)はletと同じ位置にインデントします。
    3*x + 5*y ;;

 ▼

val testVal : int = 13
letと関数のバインド(束縛)

 letキーワードを用いると、C#の場合と同様のプリミティブ型やオブジェクト型だけでなく、関数型の識別子を定義することもできます。

[構文]let:関数のバインド(束縛)
let 識別子 パラメーターリスト [: 戻り値の型] =
   式(expression)
本文式(body-expression)

 リスト6は、「testaddint は、int型の値をパラメーターとして渡し、さらに、もう1つのint型の値をパラメーターとして渡すと、int型の戻り値を返す関数である」という定義です。[testaddint 2 5 ;;]は、実際にこのtestaddint関数に 「2」と「5」の2つの引数を渡していて、結果int型の「7」が返されました。

 この例では、識別子の持つ型が明示的に定義されていないにも関わらず、続く式の右辺から型が推定されています。これが型推論と呼ばれる機能で、コンパイラがコードを解析し推定した型を返します。ちなみに、型注釈なしの場合は"+"演算子はデフォルトとしてintを使用します。

[リスト6]パラメーターx、yを受け取る関数testaddintの定義
// testaddint関数の定義
> let testaddint x y = x + y ;;

 ▼

val testaddint : int -> int -> int
// testaddint関数に引数を与え呼び出し
> testaddint 2 5 ;;

 ▼

val it : int = 7

 下記の関数testaddstrの定義では、1つ目のパラメーターに型をあらかじめ指定します。左側の値として、string型の値を受け付けたときの"+"演算子は、string型の値のみ右側の値として受け付けるため、yもstring型である必要があります。

 string型のxがパラメーターとして渡され、さらにstring型のyが渡され、string型の値が戻り値として返される関数staddstrを定義します。1つめのパラメーター"2"はstring型として扱われます。結果、2つめのパラメーター(演算子"+"の右側の値)もstring型である必要があります。

[リスト7]パラメーターx(string型)、yを受け取る関数testaddstrの定義
// testaddstr関数の定義
> let testaddstr (x : string) y = x + y ;;

 ▼

val testaddstr : string -> string -> string
// testaddstr関数に引数を与え呼び出し
> testaddstr "2" "5" ;;

 ▼

val it : string = "25"

ラムダ式

 C# 3.0ユーザーにはおなじみかもしれませんが、F#においても必要に応じて作成される名前のない関数としてラムダ式(匿名関数)が存在します。ラムダ式にはfunというキーワードを使用します。

[構文]ラムダ式
fun パラメーターリスト -> 式

 以下は、パラメータiを受け取り、i * i の実行結果を返す匿名の関数(ラムダ式)の例です。List.map は後続のリスト内の各要素に対して関数を適用します。つまり、リスト[1;2;3]の要素を1つずつラムダ式に渡し、i * i を実行し結果をtestlistというリストに入れます。最終的にtestlistには [1;4;9]という要素が入ります。

[リスト8]List.mapにラムダ式(匿名関数)とリストを渡し実行する関数testlistの定義
> let testlist = List.map (fun i -> i * i) [1;2;3] ;;

 ▼

val testlist : int list = [1; 4; 9]

F#固有のデータ型

 F#には、他.NET言語で使用できる従来のデータ型のシームレスなサポートに加え、新たにF#固有の型も追加されています。

Unit(ユニット)

 厳密に言うと、F#において関数は必ず値を返します。ただし、返されるのが通常の値ではなく、unit(ユニット)という特定の型である場合もあります。ユニット型の唯一の値は"()"です。他の値が存在しない、もしくは必要ないときにはプレースホルダーとして使用されます。とりあえず、C#のvoidのようなものと覚えておけばOKです。以下は、unit" ()"を用いた引数を受け付けず、値を戻さない関数の例です。

[リスト9]引数を受け付けず値を返さない関数aの定義
> let a () = () ;;

 ▼

val a : unit -> unit
組(Tuple:タプル)

 配列やリストは同じ型の複数の値をまとめる機能ですが、これに対して「組」は、型が異なる2つ以上の関連付けられた複数の値をまるで一つの値のように扱う機能です。値はコンマで区切られます。カッコをつけるかどうかは任意ですが、つけた方が見やすいでしょう。

[構文]組(タプル)
 (要素1, ……, 要素n)

 下記の例は、(11111, true, “Hello world!”)という3つの異なる型の要素からなる1つの組をtupletestに束縛しています。

[リスト10]tupletestに3つの異なる型の値の組をバインド
> let tupletest = (11111, true, "Hello world!") ;;

 ▼

 val tupletest : int * bool * string = (11111, true, "Hello world!")

まとめ

 今回はC#との比較というよりもF#の基本的な構文を中心に紹介しましたが、次回は再帰関数や、高階関数の例を用いながら、「関数型言語としてのF#」をテーマにC#とF#の機能を比較し、解説する予定です。



  • LINEで送る
  • このエントリーをはてなブックマークに追加

修正履歴

  • 2009/09/05 08:09 「let関数」という記述をすべて削除し、「letバインド(束縛)」もしくは、「let」に修正

バックナンバー

連載:C#プログラマのためのF#入門

もっと読む

著者プロフィール

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

  • WINGSプロジェクト 星山 仁美(ホシヤマ ヒトミ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5