質問
ここ StackOveflow には次のグループがあるようです F# 愛好家。
私はこの言語をもっとよく知りたいので、 関数型プログラミング理論, 、F# 言語の使用を開始するためのより良い出発点を教えてください。つまり、チュートリアル、ハウツーですが、まず第一に、何かを始めて言語を楽しむための作業サンプルです。
どうもありがとう
アンドレア
解決
ひどく自分を卑劣にするつもりはありませんが、ブログに F# の概要に関する投稿をいくつか書きました ここ そして ここ. 。Chris Smith (MS の F# チームのメンバー) には、「20 分でわかる F#」という記事があります。 パート1 そして パート2.
F# の最新の CTP (バージョン 1.9.6.0) には、以前のバージョンと比較して重大な変更がいくつか含まれているため、一部の例やチュートリアルは変更しないと動作しない可能性があることに注意してください。
ここにいくつかの素晴らしい内容を簡単にまとめます。おそらく私自身がここでいくつかのヒントを提供できるかもしれません。 とても 短いのであまり良くないかもしれませんが、何か遊んでいただけると幸いです!:-
最初の注意事項 - インターネット上のほとんどの例では、「軽量構文」がオンになっていることが前提となっています。これを実現するには、次のコード行を使用します。
#light
これにより、OCaml 互換性のために存在する特定のキーワードを挿入したり、各行をセミコロンで終了したりする必要がなくなります。この構文を使用すると、インデントによってスコープが定義されることに注意してください。これは後の例で明らかになりますが、これらはすべて軽量構文がオンになっていることに依存しています。
対話モードを使用している場合は、すべてのステートメントを 2 つのセミコロンで終了する必要があります。次に例を示します。
> #light;;
> let f x y = x + y;;
val f : int -> int -> int
> f 1 2;;
val it : int = 3
対話モードでは、各行の後に「val」結果が返されることに注意してください。これにより、作成中の定義に関する重要な情報が得られます (例: 'val f :)。int -> int -> int' は、2 つの int を受け取る関数が int を返すことを示します。
インタラクティブの場合のみセミコロンで行を終了する必要があることに注意してください。実際に F# コードを定義するときは、その必要はありません :-)
「let」キーワードを使用して関数を定義します。これはおそらく F# 全体で最も重要なキーワードであり、頻繁に使用することになります。例えば:-
let sumStuff x y = x + y
let sumStuffTuple (x, y) = x + y
これらの関数は次のように呼び出すことができます:-
sumStuff 1 2
3
sumStuffTuple (1, 2)
3
ここで関数を定義するには 2 つの異なる方法があることに注意してください。パラメータを空白で区切るか、「タプル」でパラメータを指定することができます (つまり、括弧内の値はカンマで区切られます)。違いは、最初のアプローチを使用すると、「部分関数適用」を使用して、必要なパラメーターより少ない関数を取得できるが、2 番目のアプローチでは使用できないことです。例えば。:-
let sumStuff1 = sumStuff 1
sumStuff 2
3
式「sumStuff 1」から関数を取得していることに注意してください。「ファーストクラス関数」を持つ言語と呼ばれるデータと同じくらい簡単に関数を渡すことができる場合、これは F# などの関数型言語の基本的な部分です。
パターン マッチングは非常にクールで、基本的には強化された switch ステートメントのようなものです (そう、別の F# 主義者からそのフレーズを拝借しました :-)。次のようなことができます:-
let someThing x =
match x with
| 0 -> "zero"
| 1 -> "one"
| 2 -> "two"
| x when x < 0 -> "negative = " + x.ToString()
| _ when x%2 = 0 -> "greater than two but even"
| _ -> "greater than two but odd"
何かに一致させたいが、返される式が入力に依存しない場合は、「_」記号を使用することに注意してください。
必要に応じて、if、elif、else ステートメントを使用してパターン マッチングを省略できます。
let negEvenOdd x = if x < 0 then "neg" elif x % 2 = 0 then "even" else "odd"
F# リスト (その下でリンク リストとして実装されている) は次のように操作できます。
let l1 = [1;2;3]
l1.[0]
1
let l2 = [1 .. 10]
List.length l2
10
let squares = [for i in 1..10 -> i * i]
squares
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
let square x = x * x;;
let squares2 = List.map square [1..10]
squares2
[1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
let evenSquares = List.filter (fun x -> x % 2 = 0) squares
evenSqares
[4; 16; 36; 64; 100]
List.map 関数は、square 関数を 1 から 10 までのリストに「マップ」していることに注意してください。各要素に関数を適用します。List.filter は、提供された述語関数を通過するリスト内の値のみを返すことによってリストを「フィルター」します。「fun x -> f」構文にも注意してください。これは F# ラムダです。
全体を通して型を定義していないことに注意してください。F# コンパイラ/インタープリタは型を「推測」します。使い方からあなたが望むものを見つけ出します。例えば:-
let f x = "hi " + x
ここでは、x が文字列である必要がある操作を実行しているため、コンパイラ/インタープリタは x が文字列であると判断します。また、戻り値の型が文字列になることも決定します。
あいまいさがある場合、コンパイラーは次のような仮定を立てます。
let f x y = x + y
ここで、x と y にはさまざまな型を指定できますが、コンパイラーのデフォルトは int です。型を定義したい場合は、型アノテーションを使用できます。
let f (x:string) y = x + y
また、関数定義の一部を区切るために x:string を括弧で囲む必要があることにも注意してください。
F# で非常に便利で頻繁に使用される 2 つの演算子は、それぞれパイプ転送演算子と関数合成演算子 |> と >> です。
|> を次のように定義します。
let (|>) x f = f x
F# で演算子を定義できることに注意してください。これは非常に素晴らしいことです :-)。
これにより、より明確な方法で物事を書くことができます。例:-
[1..10] |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0)
最初の 10 個の偶数マスを取得できるようになります。それは次のことより明らかです:-
List.filter (fun x -> x % 2 = 0) (List.map (fun x -> x * x) [1..10])
まあ、少なくとも私はそう思います:-)
>> 演算子で定義される関数構成は次のように定義されます。
let (>>) f g x = g(f(x))
つまり、操作をフォワードパイプすると、最初の関数のパラメーターのみが未指定のままになります。これは次のことができるので便利です:-
let mapFilter = List.map (fun x -> x * x) >> List.filter (fun x -> x % 2 = 0)
ここで、mapFilter は入力リストを受け入れ、前と同様にフィルタリングされたリストを返します。これは次の短縮版です:-
let mapFilter = l |> List.map (fun x -> x * x) |> List.filter (fun x -> x % 2 = 0)
再帰関数を作成したい場合は、let の後に「rec」を配置して関数を再帰関数として定義する必要があります。以下に例を示します。
いくつかのクールなもの:-
階乗
let rec fact x = if x <= 1 then 1 else x * fact (x-1)
n 番目のフィボナッチ数
let rec fib n = if n <= 1 then n else fib (n-1) + fib (n-2)
フィズバズ
let (/%) x y = x % y = 0
let fb = function
| x when x /% 15 -> "FizzBuzz"
| x when x /% 3 -> "Fizz"
| x when x /% 5 -> "Buzz"
| x -> x.ToString()
[1..100] |> List.map (fb >> printfn "%s")
とにかくそれは とても 簡単な概要ですが、少しでもお役に立てれば幸いです!!
他のヒント
間違いなく、Don Syme の優れた本「Expert F#」を購入する必要があります。この本は非常によく書かれており、初心者にも専門家にも同様に適しています。この中には、入門的な内容と、より難しい内容の両方が含まれています。600ページ近くあるのでコストパフォーマンスが良いです。
このガイドは、より機能的な C# を作成するための多くの有用なテクニックを教えてくれるだけでなく、Windows でホストされる F# アプリケーションの作成を開始するために必要なすべての参考資料も提供していることがわかりました。
この本は Apress から出版されており、付属の Web サイトは次のとおりです。http://www.expert-fsharp.com/default.aspx
@kronoz - 長い回答をありがとうございました。そこから始めるのが本当に良いです。あなたのアドバイスに従って、@vecstasy が言及した本を探してみます。
さあ、コーディングに行きましょう:-)
let thanksalot = "thanks a lot"
printfn "%s" (thanksalot);;
読んでいました 現実世界の関数型プログラミング
F# と C# の例:Tomas Petricek 著
これまでのところ、C# での実装を横に示して F# の概念を教えるのに非常に優れていると思います。OO プログラマーに最適です。
をチェックしてください F# 開発者センター. 。もあります ハブFS, 、F# 専用のフォーラム。
Visual Studio に現在の CTP リリースがある場合は、F# Tutorial プロジェクトを作成できます。これにより、その名前が示すとおりの内容を含む Tutorial.fs が提供されます。
このチュートリアルでは、より大きなコレクションも参照しています。 Microsoft での F# の例.
また、F# サンプル プロジェクトが次の場所で進行中です。 コードプレックス.
お役に立てれば、
ミシェル