Fsharp-functions

提供:Dev Guides
移動先:案内検索

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) &plus; fib (n - 2)

例1

次のプログラムはフィボナッチ1から10を返します-

let rec fib n = if n < 2 then 1 else fib (n - 1) &plus; 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