3぀のFパラダむム

はじめに


.NETプログラミングに䜕らかの圢で関係しおいる人なら誰でも、Visual Studioの次のバヌゞョンでは新しいプログラミング蚀語が既に組み蟌たれおいるこずを知っおいたす。 Fが単なるFNPをはるかに超えおいるこずを瀺すためにFNPだけがたくさんありたすが、次のすべおを曞きたした。
この蚘事は、かなりの長さにも関わらず、蚀語の完党な機胜を完党に説明するこずを意図しおいたせん。 これは簡単な抂芁であり、さたざたな機胜を実蚌するために蚭蚈されおおり、それぞれが個別の蚘事に倀するものであり、1぀の蚘事にも倀したせん。
さらに、このような長い蚘事を曞いたので、将来のために予備を䜜りたいず思ったので、将来、私は基本的なレベルの取るに足らないものに気を取られないでしょう。 もちろん、すぐに池に向かう-これは効果的ですが、どんな基盀も傷぀けたせん。
そしお、次回は、通垞のプロフェッショナルプログラミングアクティビティに察するFの適合性に関する刺激的なトピックの䟋を玹介したす。
繰り返しになりたすが、実際には倧量のテキストがありたす。 そしお、私はあなたに譊告しなかったず蚀っおはいけたせん。 =

F機胜的


もちろん、たず第䞀に、Fは関数型蚀語です。぀たり、Fで最も完党に実装されおいるのは、関数型パラダむムのサポヌトです。 ご存じのように、その䞭の倚くのキヌワヌドずリテラルはOCamlから借甚されおいたすが、Fの䞻な䜜成者であるDon Symeがか぀おOCamlに手を携えおいたので、驚くこずではありたせん。
Fに぀いおの倚くの知識は、玔粋な関数型プログラミング蚀語であり、読者は私の過去の投皿から孊んだかもしれたせんが、蚀語の完党な印象を䜜成するためだけに、すべおを簡単に繰り返したす。

識別子、キヌワヌド、機胜。


奇劙なこずに、Fを䜿甚するず、プログラマは識別子を定矩しお、埌で関数にアクセスできたす。 これは、 letキヌワヌドを䜿甚しお実行され、その埌に識別子の名前、パラメヌタヌのリスト、等号関数を定矩する匏が続きたす。 このようなもの
let k = 3.14
let square x = x**2.0

呜什型プログラミングずは異なり、最初の匏は倉数ではなく定数を定矩したす。その倀はプログラムの実行䞭に倉曎できないためです。 䞀般的に、Fは関数ず倀を区別したせん。関数はパラメヌタヌずしおも自由に枡すこずができる倀です。
すべおのFキヌワヌドのリストはここにありたす 。 参考ずしお提䟛されおいる2番目のリストの単語は、珟時点では䜿甚されおいたせんが、将来のために予玄されおいたす。 これらは䜿甚できたすが、コンパむラは譊告を出したす。
Fはカリヌ化された関数をサポヌトしたすが、すべおのパラメヌタヌを䞀床に転送できるわけではありたせん。
let add ab = a + b //'a -> 'a -> 'a
let addFour = add 4 //'a -> 'a

2番目の識別子は、1぀の空きパラメヌタヌから既に関数を定矩し、もう1぀は4ずしお定矩されおいたす。これは、関数が倀であるずいう理論をもう䞀床瀺しおいたす。 関数は倀であり、パラメヌタヌの完党なセットを受け取っおいないため、単に倀でもある別の関数を返すだけです。
ただし、.NETのすべおの関数にはカレヌ機胜のプロパティはありたせん。たた、Fで䜿甚するために、タプル耇数の異皮倀のセットが䜿甚されたす。 タプルはそれ自䜓に倚くの異なるパラメヌタヌを含むこずができたすが、Fは1぀のパラメヌタヌず芋なされ、結果ずしお党䜓にのみ適甚されたす。 タプルは、カンマで区切られた括匧内に蚘述されたす。

let add (a,b) = a + b
let addFour = add 4

Fによるず、䞍適切な型のパラメヌタヌ、぀たり 'a *'の代わりにintに関数を適甚しようずしおいるため、このようなコヌドはコンパむルされたせん。
ただし、独自の関数、特に他のプログラマが䜿甚する関数を開発する堎合は、䜿甚する柔軟性が明らかに高いため、可胜であればカレヌにする必芁があるこずに泚意しおください。
読者の皆さんは、F関数では戻り倀を明瀺的に定矩する必芁がないこずにすでに気付いおいたす。 ただし、関数内で䞭間倀を蚈算する方法は明確ではありたせんか ここでFはメ゜ッドを䜿甚したすが、その倚くは、スペヌスの助けを借りお忘れるこずができたず思いたす。 関数の内郚蚈算は通垞、4぀のスペヌスで区切られおいたす。
let midValue ab =
let dif = b - a
let mid = dif / 2
mid + a

ちなみに、Fプログラムを芋た人の1人がコヌド内に#lightコマンドが垞に存圚するこずに驚いた堎合、その効果の1぀は、スペヌスが重芁になるこずです。 これにより、 in 、;;、 begin 、 endなど、OCamlに由来する倚くのキヌワヌドず文字の䜿甚が回避されたす。
各識別子には独自の適甚分野があり、定矩の堎所から始たり぀たり、定矩の堎所よりもコヌドでそれを䜿甚するこずは䞍可胜です、定矩されたセクションの終わりで終わりたす。 たずえば、前の䟋の䞭間識別子difおよびmidは、midValue関数の倖偎では機胜したせん。
関数内で定矩された識別子は、倖郚レベルで定矩された識別子ず比范しおいく぀かの特異性がありたす-letずいう単語を䜿甚しお再定矩できたす。 これは、䞭間倀を保持するためのすべおの新しい、ほずんどの堎合ほずんど意味のない名前を発明するこずができないので䟿利です。 たずえば、前の䟋では、次のように曞くこずができたす。
let midValue ab =
let k = b - a
let k = k / 2
k + a

さらに、これは完党な意味でのオヌバヌラむドであり、倉数の倀の倉曎ではないため、識別子の倀だけでなく、その型も非垞に適切に倉曎できたす。
let changingType () =
let k = 1
let k = "string"

Fでは、マップ、リスト、フォヌルドなどのシヌケンスを凊理するバッチ機胜により、ほずんどの堎合、サむクルなしで実行できたすが、必芁な堎合は、再垰を䜿甚できたす。 理解しやすいのは、サむクルたたは再垰は䞀般に未解決の問題であり、私の意芋ではどちらもかなり実行可胜です。 Fの関数がその定矩内で自身にアクセスするためには、 letの埌にrecキヌワヌドを远加する必芁がありたす。

Fは匷く型付けされた蚀語です。぀たり、間違った型の倀を持぀関数を䜿甚するこずはできたせん。 関数は、他の倀ず同様に、独自のタむプを持っおいたす。 倚くの堎合、F自䜓が関数のタむプを掚枬し、たずえば次のようにあいたいになる堎合がありたす。
let square x = x*x

型は ' a-> ' aです。ここで、 'aはint、float、䞀般的にはanyで、*挔算子がオヌバヌロヌドされたす。
必芁に応じお、関数パラメヌタヌの型を自分で蚭定できたすたずえば、クラスメ゜ッドを䜿甚する必芁がある堎合。
let parent (x:XmlNode) = x.ParentNode


ラムダず挔算子


Fは匿名関数たたはラムダをサポヌトしたす。これらは、関数がパラメヌタヌずしお別の関数に枡されるずきに名前を付ける必芁がない堎合に䜿甚されたす。 以䞋のラムダの䟋
List.map (fun x -> x**2) [1..10]

この関数は、1から10たでのすべおの数倀の二乗で構成されるリストを䜜成したす。
さらに、Fには、 functionキヌワヌドを䜿甚しおラムダを定矩する別の方法がありたす。 この方法で定矩されたラムダには、パタヌンマッチング操䜜が含たれおいる堎合がありたすが、必芁なパラメヌタヌは1぀だけです。 ただし、この堎合でも、関数のカレヌ機胜を保存するこずは可胜です。
function x -> function y -> x + y

Fのラムダはクロヌゞャをサポヌトしたすが、これに぀いおはレビュヌの埌半でさらに詳しく説明したす。
Fでは、挔算子単項および二項は、関数を呌び出すより矎的な方法ず芋なすこずができたす。 Cず同様に、挔算子はオヌバヌロヌドされるため、さたざたな型で䜿甚できたすが、Cずは異なり、挔算子をさたざたな型のオペランドに適甚するこずはできたせん。぀たり、数字および実数を持぀敎数の文字列を远加するこずはできたせん。キャストを行いたす。
Fを䜿甚するず、挔算子をオヌバヌロヌドしたり、独自に定矩したりできたす。
let (+) ab = a - b
printfn "%d" (1 + 1) // "0"

挔算子には、次の文字の任意のシヌケンスを䜿甚できたす$* + _。/ <=>@ ^ |〜
let (+:*) ab = (a + b) * a * b
printfn "%d" (1 +:* 2) // "6"


リストの初期化


別の匷力なFテクニックは、リストを初期化するこずです。これにより、特別な構文を䜿甚しお、かなり耇雑なリスト、配列、およびシヌケンスIEnumerableに盞圓を盎接䜜成できたす。 リストは括匧[]で、シヌケンスは{}で、配列は[| |]。
最も簡単な方法は、ギャップを決定するこずです。これは、たずえば次のように..を䜿甚しお蚭定されたす。
let lst = [1 .. 10]
let seq = { 'a' .. 'z' }

たた、もう1぀..を远加するこずで、間隔の遞択ステップを蚭定できたす。
let lst = [1 .. 2 .. 10] // [1, 3, 5, 7, 9]

さらに、リストを䜜成するずきに、ルヌプを䜿甚できたすルヌプは、単䞀たたは任意の皋床にネストできたす
let lst = [for i in 1..10 -> i*i] // [1, 4, 9,..]

ただし、これだけではありたせん。 リストを初期化するずき、 yieldステヌトメント シヌケンスに1぀の芁玠を远加ずyieldを䜿甚しお、入力する芁玠を明瀺的に指定できたす。 倚くの芁玠を远加したす、テンプレヌトずの論理構造、ルヌプ、比范も䜿甚できたす。 たずえば、これは、このフォルダヌずそのすべおのサブフォルダヌに含たれるすべおのファむルの名前のシヌケンスを䜜成する方法です。
let rec xamlFiles dir filter =
seq { yield! Directory.GetFiles(dir, filter)
for subdir in Directory.GetDirectories(dir) do yield! xamlFiles subdir filter}


パタヌン比范


テンプレヌトずの比范は、通垞の条件ステヌトメントたたはスむッチに少し䌌おいたすが、より倚くの機胜がありたす。 䞀般に、操䜜構文は次のようになりたす。
match with
[|]1|2|..|10 -> 1
|11 when 1 -> 2
...

テンプレヌトずの比范は䞊から䞋に行くため、幅の狭いテンプレヌトは䞊に配眮する必芁があるこずを忘れないでください。 最も䞀般的なテンプレヌトは次のようになりたす_アンダヌスコア。これは、識別子の倀に関心がないこずを意味したす。 さらに、テンプレヌトずの比范が完了し未調査の機胜はありたせん、すべおの蚈算で同じタむプの結果が生成されたす。
テンプレヌトを䜿甚した最も単玔なタむプの操䜜では、識別子ず特定の倀数倀、文字列を比范したす。whenキヌワヌドを䜿甚するず、テンプレヌトに条件を远加しお、蚈算を実行できたす。
別の識別子が倀に眮き換えられる堎合、怜蚌された識別子の倀がそれに割り圓おられたす。
テンプレヌトず比范するために最も䞀般的に䜿甚されるオプションは、タプルずリストの䞊にありたす。 xをstring * int圢匏のタプルずするず、同様のテンプレヌトを䜜成できたす。
match x with
| "" , _ -> ", !"
| _, i when i > 200 -> ", !"
| name, age -> sprintf " %s, %d" name age
| _ -> " "

テンプレヌトに識別子がある堎合、察応する倀によっお識別子が自動的に決定され、凊理で名前フィヌルドず幎霢フィヌルドを別々に䜿甚できるこずに泚意しおください。
リストはたったく同じ方法で凊理されたすこれは実際にはリストではなく、以䞋で説明する差別化された結合です。 通垞、リスト「リスト」のテンプレヌトは、空の堎合は[]ずしお、たたはヘッド::タむプがヘッドのテヌルで、テヌルがタむプ 'aリストのいずれかです。ただし、他のオプションも可胜です。
match lst with
|[x;y;z] -> //lst , xy z.
|1::2::3::tail -> // lst [1,2,3] tail

テンプレヌトず比范するずきに識別子に倀を枡す機胜は非垞に䟿利なので、Fでは、次のようにテンプレヌト構文を䜿甚せずに、そのような割り圓おを盎接行うこずができたす。
let (name, age) = x

たたはそれでも
let (name, _) = x

タプルの最初の芁玠のみに関心がある堎合。

投皿


Fのレコヌドはタプルに䌌おいたすが、それらの各フィヌルドには名前がありたす。 ゚ントリの定矩は䞭括匧で囲たれ、セミコロンで区切られたす。
type org = { boss : string; tops :string list }
let Microsoft = { boss = "Bill Gates" ; tops = [ "Steve Balmer" , "Paul Allen" ]}

レコヌドフィヌルドには、通垞どおり、ポむントを介しおアクセスしたす。 以䞋に瀺すように、゚ントリはクラスを暡倣できたす。

タグ付きプヌル


Fのこのタむプを䜿甚するず、異なる構造ず意味を持぀デヌタを保存できたす。 たずえば、ここにタむプがありたす
type Distance =
|Meter of float
|Feet of float
|Mile of float

let d1 = Meter 10
let d2 = Feet 65.5

3皮類のデヌタはすべお同じタむプオプションですが、明らかに意味が異なりたす。 ラベル付き結合は、垞にテンプレヌトずの比范を通じお凊理されたす。
match x with
|Meter x -> x
|Feet x -> x*3.28
|Mile x -> x*0.00062

すでに述べたように、リストなどの䞀般的なデヌタ型は、マヌクアップされた結合です。 その非公匏の定矩は次のようになりたす。
type a' list =
|[]
|:: of a' * List

ずころで、䞊蚘の䟋からわかるように、Fのマヌクアップされたセットは、䞀般的な方法でパラメヌタヌ化できたす。

F呜什的



ナニットタむプ


ナニットタむプは、Cのvoidタむプに関連しおいたす。 関数が匕数を取らない堎合、その入力タむプはナニットです;倀を返さない堎合、その出力タむプはナニットです。 関数型プログラミングでは、倀を受け入れない、たたは倀を返さない関数は倀を衚したせんが、呜什型パラダむムでは、副䜜甚たずえば、入出力のために倀を持ちたす。タむプunitの唯䞀の倀の圢匏はです。 このような関数は䜕も受け入れず、䜕も行いたせんナニット->ナニット。
let doNothingWithNothing () = ()

名前の埌の括匧は、これが倀ではなく、空の入力を持぀関数であるこずを意味したす。 前述したように、関数は倀ですが、関数倀ず非関数倀には倧きな違いがありたす。2番目は1回だけ蚈算され、1番目は呌び出しごずに蚈算されたす。
倀を返す関数はすべお、ignore関数を䜿甚しおナニットタむプを返す関数に倉換できたす。 それを適甚しお、この関数では戻り倀ではなく副䜜甚にのみ関心があるこずをコンパむラに䌝えたす。

可倉キヌワヌド


知っおいるように、䞀般的な堎合、Fの識別子は䜕らかの倀で定矩できたすが、この倀は倉曎できたせん。 ただし、叀き良き呜什型倉数は䟝然ずしお有甚であるため、Fは倉数を䜜成および䜿甚するためのメカニズムを提䟛したす。 そのためには、倉数名の前にmutableキヌワヌドを蚘述する必芁があり、倀は<-挔算子を䜿甚しお倉曎できたす。
let mutable i = 0
i <- i + 1

ただし、このような倉数の䜿甚は制限されおいたす。たずえば、ラムダでのクロヌゞャず同様に、内郚関数では䜿甚できたせん。 このコヌドぱラヌをスロヌしたす
let mainFunc () =
let mutable i = 0
let subFunc () =
i <- 1


タむプref


Fでは、 ref型を䜿甚しお倉数を定矩する別の方法がありたす。 これを行うには、識別子の倀を衚す蚈算の前にキヌワヌドrefを眮きたす。
別の倀を倉数に割り圓おるには、ノスタルゞックな挔算子=を痛々しいほど䜿甚したす。倉数の倀ぞのアクセスは远加するこずで行われたす 倉数名の前。
let i = ref 0
i := !i + 1

おそらく、この衚蚘は前の衚蚘ほどきれいではありたせん。感嘆笊を䜿甚しお倀を取埗するだけの䟡倀がありたすFの吊定にはキヌワヌドはありたせん
ただし、 mutableずは異なり、 ref型にはスコヌプに関する制限がないため、ネストされた関数ずクロヌゞャヌの䞡方で䜿甚できたす。 そのようなコヌドは動䜜したす
let i = ref 2
let lst = [1..10]
List.map (fun x -> x * !i) lst


配列


Fには、可倉型の配列がありたす。 リスト内の倀ずは異なり、配列内の倀は再割り圓おできたす。 配列はそのような角括匧[| |]、その䞭の芁玠はセミコロンでリストされたす。 配列の芁玠ぞのアクセスは[Ind]を介しお行われ、代入はmutableの操䜜に慣れおいる<-挔算子によっお実行されたす。 配列を凊理するためのすべおの関数リストを凊理するためのメ゜ッドにほが類䌌は、Arrayクラスにありたす。
let arr = [|1; 2; 3|]
arr.[0] <- 10 // [|10,2,3|]

配列は、..、yieldなどを䜿甚しお、リストずたったく同じ方法で初期化できたす。
let squares = [| for x in 1..9 -> x,x*x |] // [| (1,1);(2,4);...;(9,81) |]

たた、Fを䜿甚するず、「ステップ」長さの異なるサブ配列を䜿甚ず「モノリシック」の䞡方の倚次元配列を䜜成できたす。

制埡ロゞック


Fでは、通垞の呜什型制埡ロゞック-条件挔算子if ... then ... else 、およびforルヌプずwhileルヌプを䜿甚できたす。
ifステヌトメントは関数ず芋なすこずもできるこずに泚意しおください。぀たり、どのような条件䞋でも同じ型の倀を返す必芁がありたす。 これは、 elseの䜿甚が必須であるこずも瀺唆しおいたす 。 実際、䟋倖が1぀ありたす。蚈算が行われ、条件が満たされたずきに、タむプ単䜍が返されたす。
if System.DateTime.Now.DayOfWeek = System.DayOfWeek.Sunday then
printfn " !"
printfn " !"

シフトは、ルヌプに属する関数ずそうでない関数を刀別するためにも䜿甚されたす。 たずえば、䞊の䟋では、曜日に関係なく2番目の文が衚瀺されたす。
Fのforルヌプはナニット型であるため、ルヌプ本䜓での蚈算によりこのタむプが生成されたす。そうでない堎合、コンパむラヌは譊告を出したす。
let arr = [|1..10|]
for i = 0 to Array.length arr - 1 do
printfn arr.[i]

逆方向に進みたい堎合は、叀き良き時代のようにtoを downtoに眮き換えたす。
たた、おなじみのforeachに䌌たforルヌプの別の圢匏を䜿甚するこずもできたす。
for item in arr
print_any item

whileルヌプも非垞に䞀般的で呜什型プログラマヌに銎染みがあり、その本䜓はキヌワヌドdoずdoneの間にありたすが、2番目のルヌプはオプションでシフトシステムを䜿甚しお省略できたす。

.NETラむブラリから静的メ゜ッドずオブゞェクトを呌び出す


Fで.NETツヌルキット党䜓を䜿甚できたすが、Fで蚘述されおいないすべおのメ゜ッドにはカレヌ機胜のプロパティがないため、入力芁玠のセットに察応するタプルの圢匏で匕数を指定する必芁がありたす。 この堎合、コヌルレコヌドはsyncharpず1぀のiotaを区別したせん。
#light
open System.IO
if File.Exists( "file.txt" ) then
printf " !"

ただし、.NETメ゜ッドに本圓に奜奇心を持たせたい堎合は、次のようにむンポヌトする必芁がありたす。
let exists file = File.Exists(file)

オブゞェクトの䜿甚も同様に簡単です。 新しいキヌワヌドだれが考えたでしょうかを䜿甚しお䜜成され、コンストラクタヌパラメヌタヌの適切なタプルを䜿甚したす。 letを䜿甚しおオブゞェクトに識別子を割り圓おるこずができたす。 メ゜ッド呌び出しは静的に䌌おおり、フィヌルドは<-を䜿甚しお倉曎されたす。
#light
let file = new FileInfo( "file.txt" )
if not file.Exists then
using (file.CreateText()) (fun stream ->
stream.WriteLine( "Hello world" ))
file.Attributes <- FileAttributes.ReadOnly

Fでは、オブゞェクトを䜜成するずきに、次のようにフィヌルドをすぐに初期化できたす。
let file = new FileInfo( "file.txt" , Attributes = FileAttributes.ReadOnly)


Fでむベントを䜿甚する


Fの各むベントには、むベントにハンドラヌ関数を远加するAddメ゜ッドがありたす。 ハンドラヌ関数は、タむプ 'a- > unitでなければなりたせん。 タむマヌむベントにサむンアップする方法は次のずおりです。
#light
open System.Timers
let timer = new Timer(Interval=1000, Enabled=true)
timer.Elapsed.Add(fun _ -> printfn "Timer tick!" )

むベントからのサブスクラむブ解陀は、Removeメ゜ッドを䜿甚しお行われたす。

挔算子|>


転送挔算子|>は次のように定矩されたす。
let (|>) fg = gf

最初の匕数をパラメヌタヌずしお2番目の匕数に枡したす。 もちろん、2番目の匕数は、唯䞀のパラメヌタヌずしおf型の倀を取る関数でなければなりたせん。 ちなみに、転送挔算子を䜿甚する可胜性があるため、リストの䞊にあるすべおの関数iter、map、foldはリスト自䜓を最埌に取埗したす。 次に、gずしお、劣決定関数を䜿甚できたす。
[1..10] |> List.iter (fun i -> print_int i)

たずえば、iter関数の圢匏は 'a list- > unit -> ' a list- > unitです。最初のパラメヌタヌをラムダで蚭定するず、 'a list- > unit型の関数が取埗されたす。これは匕数ずしお定矩されたリストのみを匕数ずしお受け取りたす。
プログラムは、倚くの堎合、転送挔算子の長いチェヌンを䜿甚したす。各挔算子は、前の挔算子で取埗した倀、぀たり䞀皮のパむプラむンを凊理したす。

Fオブゞェクト指向


今日のプログラミングの䞻力であるのはオブゞェクト指向のパラダむムであるず䞻匵する人はほずんどいないず思いたす。もちろん、Fはそれに含たれる抂念を無芖できたせんでした。 圌が私たちに提䟛しおくれるものを芋おみたしょう。

タむピング。


Fでは、静的な倀の型を明瀺的に倉曎するこずができたす。 Fは2぀の異なる挔算子を䜿甚しお䞊䞋にキャストしたす。 起動、぀たり、静的型にその祖先のいずれかの型の倀を割り圓おるこずは、挔算子>によっお実行されたす。 䞋の䟋のstrObj倀は、オブゞェクト型になりたす。

let strObj = ( "-, -" :> obj)

代入、぀たり、子孫のいずれかの型による倀の型の指定は、operator>によっお実行されたす。
倀のタむプアナログはCのものを確認するには、挔算子を䜿甚したす。これは、論理構造だけでなく、テンプレヌトず比范するずきにも䜿甚できたす。
match x with
|:? string -> printf " !"
|:? int -> printf " !"
|:? obj -> printf " !"

通垞、Fは、関数を蚈算するずきに型継承の階局を考慮したせん。぀たり、型継承を匕数ずしお䜿甚するこずはできたせん。 たずえば、このようなプログラムはコンパむルされたせん。
let showForm (form:Form) =
form.Show()
let ofd = new OpenFileDialog();
showForm ofd

原則ずしお、明瀺的に型をキャストできたすshowFormofd> Form、ただし、Fは別の方法を提䟛したす-関数シグネチャの型の前にポンド蚘号を远加する。
let showForm (form: #Form) =
form.Show()

したがっお、特定の関数は、Formから継承したクラスのオブゞェクトを匕数ずしお受け取りたす。

オブゞェクトずしお蚘録および結合


レコヌドず結合にメ゜ッドを远加できたす。 これを行うには、レコヌドを定矩した埌、withキヌワヌドを远加し、すべおのメ゜ッドを定矩した埌にendを蚘述し、各メ゜ッドの識別子の前にmemberキヌワヌドを䜿甚する必芁がありたす。
type Point ={
mutable x: int;
mutable y: int; }
with
member p.Swap() =
let temp = px
px <- py
py <- temp
end

メ゜ッド名の前に指定されたパラメヌタヌpは、フィヌルドにアクセスするためにその䞭で䜿甚されるこずに泚意しおください。

クラスずむンタヌフェヌス


Fのクラスは、キヌワヌド甚いお決定されおいるタむプのクラス名、等号キヌワヌドに続いお、クラス。クラス定矩はendキヌワヌドで終了したす。コンストラクタヌを指定するには、クラス定矩にnewずいう名前のメンバヌを含める必芁がありたす。
type construct = class
new () = {}
end
let inst = new construct()

クラス定矩には少なくずも1぀のコンストラクタヌが含たれおいる必芁がありたす。そうでない堎合、コヌドはコンパむルされたせん。Fは、Cのようなデフォルトのコンストラクタヌを提䟛したせん。
フィヌルドを定矩するには、その名前の前にキヌワヌドvalを远加する必芁がありたす。
type File = class
val path: string
val info : FileInfo
new () = new File( "default.txt" )
new (path) =
{ path = path;
info = new FileInfo(path) }
end
let file1 = new File( "sample.txt" )

ご芧のずおり、コンストラクタは通垞の方法でオヌバヌロヌドできたす。コンストラクタヌは䞀郚のフィヌルドを初期化せずに残すこずはできたせん。そうしないず、コヌドはコンパむルされたせん。コンストラクタヌでは、フィヌルドの初期化たたは他のコンストラクタヌの呌び出ししかできないこずに泚意しおください。コンストラクタで远加の操䜜を指定するには、その埌にを远加し、その埌にすべおの远加の蚈算を蚘述する必芁がありたす。
new (path) as x =
{ path = path;
info = new FileInfo(path) }
then
if not x.info.Exists then printf " !"

デフォルトでは、クラスのフィヌルドは䞍倉です;フィヌルドを可倉にするには、その名前の前に可倉を远加する必芁がありたす。
Fのむンタヌフェむスは、次のように定矩および実装されたす。
let ISampleInterface = interface
abstract Change : newVal : int -> unit
end

type SampleClass = class
val mutable i : int
new () = { i = 0}
interface ISampleInterface with
member x.Change y = xi <- y
end
end

Fは、クラスを定矩する別の゚レガントな方法-暗黙的な割り圓おを提䟛したす。クラス名の盎埌に入力パラメヌタヌがリストされたす。そうでなければ、コンストラクタヌ匕数に含たれたす。クラスの構築は、メ゜ッドの定矩に先行するletシヌケンスの助けを借りお、その本䜓で盎接行われたす。この方法で定矩されたすべおの識別子は、クラスに察しおプラむベヌトになりたす。クラスのフィヌルドずメ゜ッドは、memberキヌワヌドを䜿甚しお蚭定されたす。すぐに䟋を参照するこずをお勧めしたす。
type Counter (start, inc, length) = class
let finish = start + length
let mutable current = start
member c.Current = current
member c.Inc () =
if current > finish then failwith "-!"
current <- current + inc
end

let count = new Counter(0, 5, 100)
count.Inc()

FはCのように、単䞀の継承のみをサポヌトし、耇数のむンタヌフェヌスを実装したす。継承は、キヌワヌド䜿甚しお指定された継承盎埌のクラスを

type Base = class
val state : int
new () = {state = 0}
end

type Sub = class
inherit Base
val otherState : int
new () = {otherState = 0}
end

明瀺的に基本的な空のコンストラクタヌを呌び出す必芁はありたせん。子孫コンストラクタヌが呌び出されるず、空の祖先コンストラクタヌが自動的に呌び出されたす。祖先にそのようなコンストラクタヌがない堎合は、inheritキヌワヌドを䜿甚しお、子孫コンストラクタヌで基本コンストラクタヌを明瀺的に呌び出す必芁がありたす。
Fのプロパティは次のように定矩されたす。
type PropertySample = class
let mutable field = 0
member x.Property
with get () = field
and set v = field <- rand
end

静的フィヌルドを決定するための郚材キヌワヌド远加静的クラスの陀去パラメヌタobznachayuschyむンスタンス。
type StaticSample = class
static member TrimString (st:string) = st.Trim()
end


おわりに



今日、私たちは蚀語の基本的な機胜のほずんどを簡単に調べ、芋たものに基づいおいく぀かの結論を導き出すこずができたす。
実際、Cで䜿甚可胜なクラスず倉数を䜿甚した操䜜はFでも実行できるため、この蚀語は、お兄さんほどオブゞェクト指向ではありたせん。その䞭の構文はおそらくもっず耇雑ですが、重芁ではなく、それは習慣の問題のようです。䞀方、機胜面では、F、予想通り実際、ここで説明されおいるので、さらに予想されるはずです

Source: https://habr.com/ru/post/J55272/


All Articles