F#-関数

F#では、関数はデータ型のように機能します。他の変数と同じように関数を宣言して使用できます。

関数は他の変数と同じように使用できるので、次のことができます。

  • 名前を使用して関数を作成し、その名前をタイプに関連付けます。
  • 値を割り当てます。
  • その値に対して計算を実行します。
  • パラメータとして別の関数またはサブルーチンに渡します。
  • 別の関数の結果として関数を返します。

関数の定義

関数は、を使用して定義されます letキーワード。関数定義の構文は次のとおりです-

let [inline] function-name parameter-list [ : return-type ]
   = function-body

どこ、

  • function-name 関数を表す識別子です。

  • 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

戻り値の型は、チェーン矢印表記の右端のデータ型で表されます。

さらにいくつかの例-

表記 意味
フロート→フロート→フロート この関数は2つのfloat入力を受け取り、別のfloatを返します。
int→string→float この関数はint文字列の入力を受け取り、floatを返します。

ラムダ式

A lambda expression 名前のない関数です。

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#は、と呼ばれる機能も提供します pipelining of functions. パイプライン化により、関数呼び出しを連続した操作としてチェーン化できます。

次の例は、次のことを示しています。

let function1 x = x + 1
let function2 x = x * 5

let res = 10 |> function1 |> function2
printfn "%d" res

プログラムをコンパイルして実行すると、次の出力が生成されます。

55