CodeZine(コードジン)

特集ページ一覧

F#のオブジェクト式とミュータブルオブジェクト

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

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

目次

 次に、同様の作業を参照セルで行ってみます。

[リスト4]参照セル操作
let xRef = ref 3;;  //※5 参照セルの新規作成
xRef := !xRef + 1;;  //※6
xRef;;
!xRef;;

let yRef = xRef;;  //※7
yRef := !yRef + 1;;  //※8
yRef;;
!yRef;;
xRef;;
!xRef;;

 ▼


val xRef : int ref = {contents = 3;}
> val it : unit = ()
>val it : int ref = {contents = 4;}
>val it : int = 4
>val yRef : int ref = {contents = 4;}

>val it : unit = ()
>val it : int ref = {contents = 5;}
>val it : int = 5
>val it : int ref = {contents = 5;}
>val it : int = 5 

 以下の参照セルの操作のイメージ図を見てください。

参照セルオブジェクトの操作
参照セルオブジェクトの操作

 xRefにint ref型(参照セル)の3をバインド(※5)します。

 ※6のxRefの前にある!ですが、参照セルの前に置くことで、参照セルが示す場所にある値を返します。:=は代入演算子で値を変更する際に使用します。

 つまり、※6の部分ではxRef1が指す場所にある値3に1を追加し、それをxRefに代入しています。

 ※7で、yRefにxRefをバインドします。※8では、yRefが指し示す場所(すなわちxRefも指している)にある値を変更します。したがって変更後は、!yRefで読み込まれる値だけではなく、!xRefの値も変更されています。

制約

 次に、前回までの連載で説明を省いていた機能制約について説明します。

 F#にもC#同様に、ジェネリック型やファンクションで型引数用に要件を指定するために、ジェネリック型のパラメータに適用できる制約という機能があります。

[構文]
型パラメータリスト when 制約1 [ and制約2]

 制約を適用したい型パラメータのリストの後に、whenと制約を追加します。

 制約には下記のようなものがありますが、最も使用されるのは型制約で、その他はライブラリによってある機能を実装するために使用されるか、主にCLIでサポートされる一連の制約に対しての互換性のためのものです。

制約の種類
制約の種類 構文 役割
型制約 型パラメータ:> 型 型は:>オペレータの後に指定された型を継承するものか同じのものでなくてはならない。インターフェイス型の場合には、そのインターフェイスを実装しなくてはならない
Null制約 型パラメータ: null 型はNullに設定されるケースをサポートしなくてはならない。F#のlist、組、関数、クラス、レコード、ユニオン型意外の全ての.NETオブジェクト型を含む
明示的メンバー制約 型パラメータ[or ... or 型パラメータ] : メンバーシグネチャ 最低1つの型引数が指定されたシグネチャを持つメンバーを持つ必要がある。一般的には余り用いられない
コンストラクター制約 型パラメータ : ( new : unit -> 型 型はデフォルトコンストラクターを持つ必要がある
値型制約 : struct 型は .NETの値型である必要がある
参照型制約 : not struct 型は.NETの参照型である必要がある
列挙型制約 : enum<ベースとなる型> 型は指定されたベース型を持つ列挙型である必要がある。一般的には余り用いられない
デレゲート制約 : delegate<組パラメータ型, 戻り値型> ジェネリック型は指定された引数と戻り値を持つデレゲートである必要がある。一般的には余り用いられない
比較制約 : comparison 型は比較機能をサポートする必要がある
等式比較 : equality 型は等式機能をサポートする必要がある
アンマネージド制約 : unmanaged 型はアンマネージ型である必要がある。sbyte, byte, char, nativeint、unativeint、float32、float、int16、uint16、int32、uint32、int64、uint64、decimalなどの基本型、列挙型 nativeptr<_>型や、アンマネージ型のフィールドだけで構成された非ジェネリックの構造体などのいずれかである必要がある

型制約

 以下は、型パラメータの引数として使用できる型に対する制約を指定する、型制約の使用例です。

[リスト5]C#の型制約の例
class GenericList<T> where T : BaseClass
{
:
}

 制約により、T型のすべての項目がBaseClassオブジェクト、またはBaseClassから継承されたオブジェクトのいずれかであることが保証されています。

[リスト6]F#の型制約の例
type 'a genericType when 'a :> BaseClass = class
:
end

 F#の構文に従ってwhenと:>を使用して型制約を定義します。

 制約により、’a型のすべての項目がBaseClassオブジェクト、またはBaseClassから継承されたオブジェクトのいずれかであることが保証されています。

メンバー制約

 次に、メンバー制約について説明します。

 メンバー制約は、提供された型パラメータがある種のシグネチャを持つことを保証するためのものです。F#ライブラリでオーバーロードファンクションを定義する際などによく使用されます。オーバーロードファンクションとは、同一名の演算子記号やメソッドを複数定義し、IDなどを使用して区別し、状況に応じて選択して使用させる機能のことです。メンバー制約を有効にするためには、inline修飾子をつけます。

[リスト7]F#のメンバー制約の例
let testMethod1 x = x + x
let inline testMethod x = x + x;;

 ▼

val testMethod1 : int -> int

val inline testMethod :

   ^a ->  ^b when  ^a : (static member ( + ) :  ^a *  ^a ->  ^b)

 例えば、上記リスト7において、inlineなしの場合メンバー制約は有効にはならないため、関数testMethod1は1種類のみ(例:int)の値が対象になります。しかし、inlineを使用した場合はメンバー制約が有効になるので、関数testMethod2は汎用的な関数となり、対象の値はジェネリックになります。


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

バックナンバー

連載: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