Fsharp-functions
F#-関数
F#では、関数はデータ型のように機能します。 他の変数と同じ方法で関数を宣言して使用できます。
関数は他の変数と同様に使用できるため、次のことができます-
- 名前を持つ関数を作成し、その名前をタイプに関連付けます。
- 値を割り当てます。
- その値に対して何らかの計算を実行します。
- パラメータとして別の関数またはサブルーチンに渡します。
- 別の関数の結果として関数を返します。
関数を定義する
関数は let キーワードを使用して定義されます。 関数定義には次の構文があります-
let [inline] function-name parameter-list [ : return-type ]
= function-body
どこで、
- *関数名*は、関数を表す識別子です。
- parameter-list は、スペースで区切られたパラメーターのリストを提供します。 各パラメーターに明示的な型を指定することもできます。指定しない場合、コンパイラーは関数本体(変数など)からそれを推測する傾向があります。
- function-body は、式、または複数の式で構成される複合式で構成されます。 関数本体の最後の式は戻り値です。
- return-type はコロンの後にタイプが続き、オプションです。 戻りタイプが指定されていない場合、コンパイラーは関数本体の最終式からそれを判別します。
関数のパラメーター
関数名の直後にパラメーターの名前をリストします。 パラメーターのタイプを指定できます。 パラメーターのタイプは、コロンで区切られたパラメーターの名前に従う必要があります。
パラメータタイプが指定されていない場合、コンパイラによって推測されます。
たとえば-
let doubleIt (x : int) = 2 *x
関数を呼び出す
関数を呼び出すには、関数名の後にスペースを続け、その後にスペースで区切った引数を指定します。
たとえば-
let vol = cylinderVolume 3.0 5.0
次のプログラムは、概念を示しています。
例1
次のプログラムは、半径と長さがパラメーターとして与えられたときにシリンダーの体積を計算します
//the function calculates the volume of
//a cylinder with radius and length as parameters
let cylinderVolume radius length : float =
//function body
let pi = 3.14159
length* pi *radius* radius
let vol = cylinderVolume 3.0 5.0
printfn " Volume: %g " vol
あなたがプログラムをコンパイルして実行すると、次の出力が得られます-
Volume: 141.372
例2
次のプログラムは、指定された2つのパラメータの大きい値を返します-
//the function returns the larger value between two
//arguments
let max num1 num2 : int32 =
//function body
if(num1>num2)then
num1
else
num2
let res = max 39 52
printfn " Max Value: %d " res
あなたがプログラムをコンパイルして実行すると、次の出力が得られます-
Max Value: 52
実施例3
let doubleIt (x : int) = 2 * x
printfn "Double 19: %d" ( doubleIt(19))
あなたがプログラムをコンパイルして実行すると、次の出力が得られます-
Double 19: 38
再帰関数
再帰関数は、それ自体を呼び出す関数です。
*let rec* キーワードの組み合わせを使用して、再帰を定義します。
再帰関数を定義するための構文は-
//Recursive function definition
let rec function-name parameter-list = recursive-function-body
たとえば-
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)
例1
次のプログラムはフィボナッチ1から10を返します-
let rec fib n = if n < 2 then 1 else fib (n - 1) + fib (n - 2)
for i = 1 to 10 do
printfn "Fibonacci %d: %d" i (fib i)
あなたがプログラムをコンパイルして実行すると、次の出力が得られます-
Fibonacci 1: 1
Fibonacci 2: 2
Fibonacci 3: 3
Fibonacci 4: 5
Fibonacci 5: 8
Fibonacci 6: 13
Fibonacci 7: 21
Fibonacci 8: 34
Fibonacci 9: 55
Fibonacci 10: 89
例2
次のプログラムは階乗8を返します-
open System
let rec fact x =
if x < 1 then 1
else x * fact (x - 1)
Console.WriteLine(fact 8)
あなたがプログラムをコンパイルして実行すると、次の出力が得られます-
40320
F#の矢印表記
F#は、連鎖矢印表記を使用して、関数と値のデータ型について報告します。 1つの_int_入力を受け取り、文字列を返す関数の例を見てみましょう。 矢印表記では、それは次のように書かれています-
int -> string
データ型は左から右に読み取られます。
2つのintデータ入力を受け取り、文字列を返す別の仮想関数を考えてみましょう。
let mydivfunction x y = (x/y).ToString();;
F#は、連鎖矢印表記を使用してデータ型を報告します-
val mydivfunction : x:int -> y:int -> string
戻り値の型は、連鎖矢印表記の右端のデータ型で表されます。
いくつかのより多くの例-
Notation | Meaning |
---|---|
float → float → float | The function takes two float inputs, returns another float. |
int → string → float | The function takes an int and a string input, returns a float. |
ラムダ式
- lambda式*は名前のない関数です。
2つの機能の例を見てみましょう-
let applyFunction ( f: int -> int -> int) x y = f x y
let mul x y = x *y
let res = applyFunction mul 5 7
printfn "%d" res
あなたがプログラムをコンパイルして実行すると、次の出力が得られます-
35
さて、上記の例では、関数_mul、_を定義する代わりに、ラムダ式を次のように使用できます-
let applyFunction ( f: int -> int -> int) x y = f x y
let res = applyFunction (fun x y -> x* y ) 5 7
printfn "%d" res
あなたがプログラムをコンパイルして実行すると、次の出力が得られます-
35
関数の構成とパイプライン
F#では、1つの関数を他の関数から構成できます。
次の例は、2つの関数function1とfunction2から、fという名前の関数の構成を示しています-
let function1 x = x + 1
let function2 x = x * 5
let f = function1 >> function2
let res = f 10
printfn "%d" res
あなたがプログラムをコンパイルして実行すると、次の出力が得られます-
55
F#は、*関数のパイプライン化*と呼ばれる機能も提供します。パイプライン化により、関数呼び出しを連続した操作として連鎖させることができます。
次の例は、それを示しています-
let function1 x = x + 1
let function2 x = x * 5
let res = 10 |> function1 |> function2
printfn "%d" res
あなたがプログラムをコンパイルして実行すると、次の出力が得られます-
55