Fsharp-quick-guide

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

F#-概要

F#は関数型プログラミング言語です。 F#の構造を理解するには、 Functional Programming という名前のプログラミングパラダイムに関する2、3行を読む必要があります。

関数型プログラミングでは、コンピュータープログラムを数学関数として扱います。 関数型プログラミングでは、変数と状態ではなく、定数と関数に焦点が当てられます。 なぜなら関数と定数は変わらないものだからです。

関数型プログラミングでは、モジュール式プログラムを作成します。つまり、プログラムは、他の関数を入力として受け取る関数で構成されます。

関数型プログラミング言語で書かれたプログラムは簡潔になる傾向があります。

F#について

F#に関する基本情報は次のとおりです-

  • 2005年にMicrosoft Researchで開発されました。
  • これは、Microsoftの.Net言語ファミリーの一部です。
  • 関数型プログラミング言語です。
  • 関数型プログラミング言語OCamlに基づいています。

F#の機能

  • OCamlの.Net実装です。
  • CLR(共通言語ランタイム)で実行される.Net CLI(共通言語インターフェイス)バイトコードまたはMSIL(Microsoft中間言語)をコンパイルします。
  • 型推論を提供します。
  • 豊富なパターンマッチング構造を提供します。
  • インタラクティブなスクリプト作成およびデバッグ機能があります。
  • 高階関数を書くことができます。
  • よく開発されたオブジェクトモデルを提供します。

F#の使用

F#は通常、次の分野で使用されます-

  • 科学モデルの作成
  • 数学的問題解決
  • 人工知能研究
  • 財務モデリング
  • グラフィックデザイン
  • CPU設計
  • コンパイラープログラミング
  • テレコミュニケーション

また、CRUDアプリ、Webページ、GUIゲーム、その他の汎用プログラムでも使用されます。

F#-環境設定

この章では、F#プログラミングに必要なツールについて説明します。

F#の統合開発環境(IDE)

Microsoftは、F#プログラミング用にVisual Studio 2013を提供しています。

無料のVisual Studio 2013 Community Editionは、Microsoftの公式Webサイトから入手できます。 Visual Studio 2013コミュニティ以上には、Visual F#ツールが付属しています。 リンク:/asp.net/asp.net_environment_setup [Asp.net Tutorial]にあるインストールの詳細。VisualF#ツールには、コマンドラインコンパイラ(fsc.exe)とF#Interactive(fsi.exe)が含まれています。

Visual Studio Installer

これらのツールを使用すると、単純なコマンドラインアプリケーションからより複雑なアプリケーションまで、あらゆる種類のF#プログラムを作成できます。 メモ帳などの基本的なテキストエディターを使用してF#ソースコードファイルを記述し、コマンドラインコンパイラーを使用してコードをアセンブリにコンパイルすることもできます。

Microsoft Visual Studioからダウンロードできます。 マシンに自動的にインストールされます。

リンク上のF#プログラムの作成

ツールをDebianパッケージとして入手する方法、またはソースから直接コンパイルする方法の最新の手順については、F#公式Webサイトをご覧ください-https://fsharp.org/use/linux/[[[1]]]

F#-プログラム構造

F#は関数型プログラミング言語です。

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

一般に、F#アプリケーションには特定のエントリポイントはありません。 コンパイラは、ファイル内のすべての最上位ステートメントを上から下に実行します。

ただし、手続き型プログラミングスタイルに従うために、多くのアプリケーションはメインループを呼び出す単一のトップレベルステートメントを保持します。

次のコードは、単純なF#プログラムを示しています-

open System
( *This is a multi-line comment* )
//This is a single-line comment

let sign num =
   if num > 0 then "positive"
   elif num < 0 then "negative"
   else "zero"

let main() =
   Console.WriteLine("sign 5: {0}", (sign 5))

main()

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

sign 5: positive

次のことに注意してください-

  • F#コードファイルは、名前空間のインポートに使用される多くの open ステートメントで始まる場合があります。
  • ファイルの本文には、アプリケーションのビジネスロジックを実装する他の関数が含まれています。
  • メインループには、上位の実行可能ステートメントが含まれます。

F#-基本的な構文

F#プログラムの基本構造を見てきましたので、F#プログラミング言語の他の基本的な構成要素を簡単に理解できます。

F#のトークン

F#プログラムは、さまざまなトークンで構成されています。 トークンは、キーワード、識別子、定数、文字列リテラル、またはシンボルです。 私たちはF#トークンを2つのタイプに分類できます-

  • キーワード
  • 記号と演算子

F#キーワード

次の表に、キーワードとキーワードの簡単な説明を示します。 これらのキーワードの使用については、以降の章で説明します。

Keyword Description
abstract Indicates a method that either has no implementation in the type in which it is declared or that is virtual and has a default implementation.
and Used in mutually recursive bindings, in property declarations, and with multiple constraints on generic parameters.
as Used to give the current class object an object name. Also used to give a name to a whole pattern within a pattern match.
assert Used to verify code during debugging.
base Used as the name of the base class object.
begin In verbose syntax, indicates the start of a code block.
class In verbose syntax, indicates the start of a class definition.
default Indicates an implementation of an abstract method; used together with an abstract method declaration to create a virtual method.
delegate Used to declare a delegate.
do Used in looping constructs or to execute imperative code.
done In verbose syntax, indicates the end of a block of code in a looping expression.
downcast Used to convert to a type that is lower in the inheritance chain.
*downto * In a* for* expression, used when counting in reverse.
elif Used in conditional branching. A short form of else if.
else Used in conditional branching.
end

In type definitions and type extensions, indicates the end of a section of member definitions.

冗長構文では、beginキーワードで始まるコードブロックの終了を指定するために使用されます。

exception Used to declare an exception type.
extern Indicates that a declared program element is defined in another binary or assembly.
false Used as a Boolean literal.
finally Used together with try to introduce a block of code that executes regardless of whether an exception occurs.
for Used in looping constructs.
fun Used in lambda expressions, also known as anonymous functions.
function Used as a shorter alternative to the fun keyword and a match expression in a lambda expression that has pattern matching on a single argument.
global Used to reference the top-level .NET namespace.
if Used in conditional branching constructs.
in Used for sequence expressions and, in verbose syntax, to separate expressions from bindings.
inherit Used to specify a base class or base interface.
inline Used to indicate a function that should be integrated directly into the caller’s code.
interface Used to declare and implement interfaces.
internal Used to specify that a member is visible inside an assembly but not outside it.
lazy Used to specify a computation that is to be performed only when a result is needed.
let Used to associate, or bind, a name to a value or function.
let! Used in asynchronous workflows to bind a name to the result of an asynchronous computation, or, in other computation expressions, used to bind a name to a result, which is of the computation type.
match Used to branch by comparing a value to a pattern.
member Used to declare a property or method in an object type.
module Used to associate a name with a group of related types, values, and functions, to logically separate it from other code.
mutable Used to declare a variable, that is, a value that can be changed.
namespace Used to associate a name with a group of related types and modules, to logically separate it from other code.
new

Used to declare, define, or invoke a constructor that creates or that can create an object.

また、型に特定のコンストラクターが必要であることを示すために、汎用パラメーター制約で使用されます。

not Not actually a keyword. However, not struct in combination is used as a generic parameter constraint.
null

Indicates the absence of an object.

汎用パラメーター制約でも使用されます。

of Used in discriminated unions to indicate the type of categories of values, and in delegate and exception declarations.
open Used to make the contents of a namespace or module available without qualification.
or Used with Boolean conditions as a Boolean or operator. Equivalent to

.

メンバー制約でも使用されます。

override Used to implement a version of an abstract or virtual method that differs from the base version.
private Restricts access to a member to code in the same type or module.
public Allows access to a member from outside the type.
rec Used to indicate that a function is recursive.
return Used to indicate a value to provide as the result of a computation expression.
return! Used to indicate a computation expression that, when evaluated, provides the result of the containing computation expression.
select Used in query expressions to specify what fields or columns to extract. Note that this is a contextual keyword, which means that it is not actually a reserved word and it only acts like a keyword in appropriate context.
static Used to indicate a method or property that can be called without an instance of a type, or a value member that is shared among all instances of a type.
struct

Used to declare a structure type.

汎用パラメーター制約でも使用されます。

モジュール定義のOCaml互換性のために使用されます。

then

Used in conditional expressions.

オブジェクトの構築後に副作用を実行するためにも使用されます。

to Used in for loops to indicate a range.
true Used as a Boolean literal.
try Used to introduce a block of code that might generate an exception. Used together with with or finally.
type Used to declare a class, record, structure, discriminated union, enumeration type, unit of measure, or type abbreviation.
upcast Used to convert to a type that is higher in the inheritance chain.
use Used instead of let for values that require Dispose to be called to free resources.
use! Used instead of let! in asynchronous workflows and other computation expressions for values that require Dispose to be called to free resources.
val Used in a signature to indicate a value, or in a type to declare a member, in limited situations.
void Indicates the .NET void type. Used when interoperating with other .NET languages.
when Used for Boolean conditions (when guards) on pattern matches and to introduce a constraint clause for a generic type parameter.
while Introduces a looping construct.
with Used together with the match keyword in pattern matching expressions. Also used in object expressions, record copying expressions, and type extensions to introduce member definitions, and to introduce exception handlers.
yield Used in a sequence expression to produce a value for a sequence.
yield! Used in a computation expression to append the result of a given computation expression to a collection of results for the containing computation expression.

いくつかの予約キーワードはOCaml言語から来ました-

asr land lor lsl lsr lxor mod sig

他の予約済みキーワードの一部は、F#の将来の拡張のために保持されています。

atomic break checked component const constraint constructor
continue eager event external fixed functor include
method mixin object parallel process protected pure
sealed tailcall trait virtual volatile

F#のコメント

F#は2種類のコメントを提供します-

  • 1行のコメントは//記号で始まります。
  • 複数行コメントは(で始まり、)で終わります。

F#の基本的なプログラムとアプリケーションエントリポイント

通常、F#プログラムの明示的なエントリポイントはありません。 F#アプリケーションをコンパイルすると、コンパイラに提供された最後のファイルがエントリポイントになり、そのファイル内のすべての最上位ステートメントが上から下に実行されます。

適切に作成されたプログラムには、プログラムのメインループを呼び出す単一のトップレベルステートメントが必要です。

画面に「Hello World」を表示する非常に最小限のF#プログラム-

( *This is a comment* )
( *Sample Hello World program using F#* )
printfn "Hello World!"

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Hello World!

F#-データ型

F#のデータ型は次のように分類できます-

  • 積分型
  • 浮動小数点型
  • テキストタイプ
  • その他の種類

積分データ型

次の表に、F#の整数データ型を示します。 これらは基本的に整数データ型です。

F# Type Size Range Example Remarks
sbyte 1 byte -128 to 127

42y

-11y

8-bit signed integer
byte 1 byte 0 to 255

42uy

200uy

8-bit unsigned integer
int16 2 bytes -32768 to 32767

42s

-11s

16-bit signed integer
uint16 2 bytes 0 to 65,535

42us

200us

16-bit unsigned integer
int/int32 4 bytes -2,147,483,648 to 2,147,483,647

42

-11

32-bit signed integer
uint32 4 bytes 0 to 4,294,967,295

42u

200u

32-bit unsigned integer
int64 8 bytes -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

42L

-11L

64-bit signed integer
uint64 8 bytes 0 to 18,446,744,073,709,551,615

42UL

200UL

64-bit unsigned integer
bigint At least 4 bytes any integer

42I

1499999

9999999

9999999

9999999

9999I

arbitrary precision integer

( *single byte integer* )
let x = 268.97f
let y = 312.58f
let z = x + y

printfn "x: %f" x
printfn "y: %f" y
printfn "z: %f" z

( *unsigned 8-bit natural number* )

let p = 2uy
let q = 4uy
let r = p + q

printfn "p: %i" p
printfn "q: %i" q
printfn "r: %i" r

( *signed 16-bit integer* )

let a = 12s
let b = 24s
let c = a + b

printfn "a: %i" a
printfn "b: %i" b
printfn "c: %i" c

( *signed 32-bit integer* )

let d = 212l
let e = 504l
let f = d + e

printfn "d: %i" d
printfn "e: %i" e
printfn "f: %i" f

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

x: 1
y: 2
z: 3
p: 2
q: 4
r: 6
a: 12
b: 24
c: 36
d: 212
e: 504
f: 716

浮動小数点データ型

次の表に、F#の浮動小数点データ型を示します。

F# Type Size Range Example Remarks
float32 4 bytes ±1.5e-45 to ±3.4e38

42.0F

-11.0F

32-bit signed floating point number (7 significant digits)
float 8 bytes ±5.0e-324 to ±1.7e308

42.0

-11.0

64-bit signed floating point number (15-16 significant digits)
decimal 16 bytes ±1.0e-28 to ±7.9e28

42.0M

-11.0M

128-bit signed floating point number (28-29 significant digits)
BigRational At least 4 bytes Any rational number.

42N

-11N

Arbitrary precision rational number. Using this type requires a reference to FSharp.PowerPack.dll.

( *32-bit signed floating point number* )
( *7 significant digits* )

let d = 212.098f
let e = 504.768f
let f = d + e

printfn "d: %f" d
printfn "e: %f" e
printfn "f: %f" f

( *64-bit signed floating point number* )
( *15-16 significant digits* )
let x = 21290.098
let y = 50446.768
let z = x + y

printfn "x: %g" x
printfn "y: %g" y
printfn "z: %g" z

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

d: 212.098000
e: 504.768000
f: 716.866000
x: 21290.1
y: 50446.8
z: 71736.9

テキストデータ型

次の表に、F#のテキストデータ型を示します。

F# Type Size Range Example Remarks
char 2 bytes U+0000 to U+ffff

'x'

'\t'

Single unicode characters
string 20 + (2 * string’s length) bytes 0 to about 2 billion characters

"Hello"

"世界"

Unicode text

let choice = 'y'
let name = "Zara Ali"
let org = "Tutorials Point"

printfn "Choice: %c" choice
printfn "Name: %s" name
printfn "Organisation: %s" org

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Choice: y
Name: Zara Ali
Organisation: Tutorials Point

その他のデータ型

次の表に、F#のその他のデータ型を示します。

F# Type Size Range Example Remarks
bool 1 byte Only two possible values, true or false

true

Stores boolean values

let trueVal = true
let falseVal = false

printfn "True Value: %b" (trueVal)
printfn "False Value: %b" (falseVal)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

True Value: true
False Value: false

F#-変数

変数は、プログラムが操作できるストレージ領域に付けられた名前です。 各変数には特定のタイプがあり、変数のメモリのサイズとレイアウトを決定します。そのメモリ内に保存できる値の範囲。変数に適用できる一連の操作。

F#の変数宣言

*let* キーワードは変数宣言に使用されます-

例えば、

let x = 10

変数xを宣言し、値10を割り当てます。

また、変数に式を割り当てることができます-

let x = 10
let y = 20
let z = x + y

次の例は、概念を示しています-

let x = 10
let y = 20
let z = x + y

printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

x: 10
y: 20
z: 30

F#の変数は*不変*です。つまり、変数が値にバインドされると、変更することはできません。 実際には、静的な読み取り専用プロパティとしてコンパイルされます。

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

let x = 10
let y = 20
let z = x + y

printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

let x = 15
let y = 20
let z = x + y

printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

あなたがプログラムをコンパイルして実行すると、次のエラーメッセージが表示されます-

Duplicate definition of value 'x'
Duplicate definition of value 'Y'
Duplicate definition of value 'Z'

型宣言を使用した変数定義

変数の定義は、変数のストレージを作成する場所と量をコンパイラに指示します。 変数定義では、データ型を指定でき、次の例に示すように、その型の1つ以上の変数のリストが含まれます。

let x:int32 = 10
let y:int32 = 20
let z:int32 = x + y

printfn "x: %d" x
printfn "y: %d" y
printfn "z: %d" z

let p:float = 15.99
let q:float = 20.78
let r:float = p + q

printfn "p: %g" p
printfn "q: %g" q
printfn "r: %g" r

あなたがプログラムをコンパイルして実行すると、次のエラーメッセージが表示されます-

x: 10
y: 20
z: 30
p: 15.99
q: 20.78
r: 36.77

可変変数

時々、変数に保存されている値を変更する必要があります。 宣言されて割り当てられた変数の値がプログラムの後半で変更される可能性があることを指定するために、F#には mutable キーワードが用意されています。 値を変更するこのキーワードを使用して、可変変数を宣言および割り当てることができます。

*mutable* キーワードを使用すると、可変変数で値を宣言して割り当てることができます。
*let* キーワードを使用して、可変変数に初期値を割り当てることができます。 ただし、新しい後続の値をそれに割り当てるには、*←*演算子を使用する必要があります。

例えば、

let mutable x = 10
x ← 15

次の例は、概念をクリアします-

let mutable x = 10
let y = 20
let mutable z = x + y

printfn "Original Values:"
printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

printfn "Let us change the value of x"
printfn "Value of z will change too."

x <- 15
z <- x + y

printfn "New Values:"
printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Original Values:
x: 10
y: 20
z: 30
Let us change the value of x
Value of z will change too.
New Values:
x: 15
y: 20
z: 35

F#-演算子

演算子は、特定の数学的または論理的な操作を実行するようコンパイラーに指示する記号です。 F#は組み込み演算子が豊富であり、次の種類の演算子を提供します-

  • 算術演算子
  • 比較演算子
  • ブール演算子
  • ビット演算子

算術演算子

次の表は、F#言語でサポートされているすべての算術演算子を示しています。 変数Aが10を保持し、変数Bが20を保持すると仮定します-

リンク:/fsharp/fsharp_arithmetic_operators [例を表示]

Operator Description Example
+ Adds two operands A + B will give 30
- Subtracts second operand from the first A - B will give -10
* Multiplies both operands A* B will give 200
/ Divides numerator by de-numerator B/A will give 2
% Modulus Operator and remainder of after an integer division B % A will give 0
** Exponentiation Operator, raises an operand to the power of another B**A will give 2010

比較演算子

次の表は、F#言語でサポートされているすべての比較演算子を示しています。 これらのバイナリ比較演算子は、整数型および浮動小数点型で使用できます。 これらの演算子は、bool型の値を返します。

変数Aが10を保持し、変数Bが20を保持すると仮定します-

リンク:/fsharp/fsharp_comparison_operators [例を表示]

Operator Description Example
= Checks if the values of two operands are equal or not, if yes then condition becomes true. (A == B) is not true.
<> Checks if the values of two operands are equal or not, if values are not equal then condition becomes true. (A <> B) is true.
> Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true. (A > B) is not true.
< Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true. (A < B) is true.
>= Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true. (A >= B) is not true.
Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true. (A ⇐ B) is true.

ブール演算子

次の表は、F#言語でサポートされているすべてのブール演算子を示しています。 変数Aが true を保持し、変数Bが false を保持すると仮定します-

リンク:/fsharp/fsharp_boolean_operators [例を表示]

Operator Description Example
&& Called Boolean AND operator. If both the operands are non-zero, then condition becomes true. (A && B) is false.
Called Boolean OR Operator. If any of the two operands is non-zero, then condition becomes true. (A
B) is true. not Called Boolean NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false.

ビット演算子

ビットごとの演算子はビットに対して機能し、ビットごとの操作を実行します。 &&&(ビットごとのAND)、|||の真理値表(ビットごとのOR)、および^(ビットごとの排他的OR)は次のとおりです-

リンク:/fsharp/fsharp_bitwise_operators [例を表示]

p q p &&& q p
q p ^ q 0 0
0 0 0 0 1
0 1 1 1 1
1 1 0 1 0

A = 60であると仮定します。およびB = 13;今バイナリ形式では、次のようになります-

A = 0011 1100

B = 0000 1101

A &&& B = 0000 1100

A ||| B = 0011 1101

A ^ B = 0011 0001

~ A = 1100 0011

F#言語でサポートされているビット演算子は、次の表にリストされています。 変数Aが60を保持し、変数Bが13を保持すると仮定します-

Operator Description Example
&&& Binary AND Operator copies a bit to the result if it exists in both operands. (A &&& B) will give 12, which is 0000 1100
Binary OR Operator copies a bit if it exists in either operand. (A
B) will give 61, which is 0011 1101
^ Binary XOR Operator copies the bit if it is set in one operand but not both. (A ^ B) will give 49, which is 0011 0001
~ Binary Ones Complement Operator is unary and has the effect of 'flipping' bits. (~A) will give -61, which is 1100 0011 in 2’s complement form.
<<< Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand. A <<< 2 will give 240 which is 1111 0000
>>> Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand. A >>> 2 will give 15 which is 0000 1111

演算子の優先順位

次の表に、F#言語の演算子およびその他の式キーワードの優先順位を、優先順位の低いものから高いものへと示します。

リンク:/fsharp/fsharp_operators_precedence [例を表示]

Operator Associativity
as Right
when Right
(pipe)
Left ;
Right let
Non associative function, fun, match, try
Non associative if
Non associative
Right :=
Right ,
Non associative or,
Left &, &&
Left < op, >op, =,
op, &op Left
&&& ,
, ^, ~, <<<, >>>
Left ^ op
Right ::
Right :?>, :?
Non associative - op, +op, (binary)
Left * op,/op, %op
Left ** op
Right f x (function application)
Left
(pattern match) Right
prefix operators (PLUSop, -op, %, %%, &, &&, !op, ~op) Left
. Left
f(x) Left
f<types> Left

F#-意思決定

意思決定構造では、プログラマがプログラムで評価またはテストする1つ以上の条件を指定する必要があります。 条件が真であると判断された場合に実行される1つ以上のステートメント、およびオプションで、条件が偽であると判断された場合に実行される他のステートメントと一緒にする必要があります。

以下は、ほとんどのプログラミング言語で見られる典型的な意思決定構造の一般的な形式です-

意思決定

F#プログラミング言語は、次のタイプの意思決定ステートメントを提供します。

Sr.No Statement & Description
1

if/then statement

  • if/thenステートメント*は、ブール式とそれに続く1つ以上のステートメントで構成されます。
2

if/then/else statement

  • if/thenステートメント*の後に、ブール式が偽の場合に実行されるオプションの* elseステートメント*を続けることができます。
3

if/then/elif/else statement

  • if/then/elif/else* ステートメントを使用すると、複数のelseブランチを作成できます。
4

nested if statements

1つの if または else if ステートメントを別の if または else if ステートメント内で使用できます。

F#-ループ

プログラミング言語は、より複雑な実行パスを可能にするさまざまな制御構造を提供します。

ループステートメントを使用すると、ステートメントまたはステートメントのグループを複数回実行できます。ほとんどのプログラミング言語では、ループステートメントの一般的な形式は次のとおりです-

ループステートメント

F#は、ループ要件を処理するために次の種類のループを提供します。

Sr.No Loop Type & Description
1

for… to and for… downto expressions

for …​ to式は、ループ変数の値の範囲でループを反復するために使用されます。 for…downto式は、ループ変数の値を減らします。

2

for … in expression

この形式のforループは、アイテムのコレクションを反復処理するために使用されます。つまり、コレクションとシーケンスをループします。

3

While…do loop

特定の条件が真の間、ステートメントまたはステートメントのグループを繰り返します。 ループ本体を実行する前に条件をテストします。

4

nested loops

他のforループまたはwhileループ内で1つ以上のループを使用できます。

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

F#-文字列

F#では、文字列型は不変テキストをUnicode文字のシーケンスとして表します。

文字列リテラル

文字列リテラルは、引用符( ")文字で区切られます。

改行、タブなどの特別な用途のためにいくつかの特殊文字があります。 バックスラッシュ(\)文字を使用してエンコードされます。 バックスラッシュ文字と関連文字は、エスケープシーケンスを作成します。 次の表は、F#でサポートされているエスケープシーケンスを示しています。

Character Escape sequence
Backspace \b
Newline \n
Carriage return \r
Tab \t
Backslash \\
Quotation mark \"
Apostrophe \'
Unicode character \uXXXX or \UXXXXXXXX (where X indicates a hexadecimal digit)

エスケープシーケンスを無視する方法

次の2つの方法により、コンパイラはエスケープシーケンスを無視します-

  • @記号を使用します。
  • 文字列を三重引用符で囲みます。

文字列リテラルの前に@記号が付いている場合、それは* verbatim文字列*と呼ばれます。その方法では、2つの引用符文字が1つの引用符文字として解釈されることを除いて、文字列内のすべてのエスケープシーケンスは無視されます。

文字列が三重引用符で囲まれている場合、二重引用符文字を含むすべてのエスケープシーケンスも無視されます。

次の例は、XMLまたは埋め込まれた引用符を含む他の構造を操作する方法を示すこの手法を示しています-

//Using a verbatim string
let xmldata = @"<book author = ""Lewis, C.S"" title = ""Narnia"">"
printfn "%s" xmldata

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

<book author = "Lewis, C.S" title = "Narnia">

文字列の基本的な演算子

次の表は、文字列の基本的な操作を示しています-

Value Description
collect : (char → string) → string → string Creates a new string whose characters are the results of applying a specified function to each of the characters of the input string and concatenating the resulting strings.
concat : string → seq<string> → string Returns a new string made by concatenating the given strings with a separator.
exists : (char → bool) → string → bool Tests if any character of the string satisfies the given predicate.
forall : (char → bool) → string → bool Tests if all characters in the string satisfy the given predicate.
init : int → (int → string) → string Creates a new string whose characters are the results of applying a specified function to each index and concatenating the resulting strings.
iter : (char → unit) → string → unit Applies a specified function to each character in the string.
iteri : (int → char → unit) → string → unit Applies a specified function to the index of each character in the string and the character itself.
length : string → int Returns the length of the string.
map : (char → char) → string → string Creates a new string whose characters are the results of applying a specified function to each of the characters of the input string.
mapi : (int → char → char) → string → string Creates a new string whose characters are the results of applying a specified function to each character and index of the input string.
replicate : int → string → string Returns a string by concatenating a specified number of instances of a string.

次の例は、上記の機能のいくつかの使用を示しています-

例1

String.collect関数は、指定された関数を入力文字列の各文字に適用し、結果の文字列を連結した結果の文字である新しい文字列を作成します。

let collectTesting inputS =
   String.collect (fun c -> sprintf "%c " c) inputS
printfn "%s" (collectTesting "Happy New Year!")

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

H a p p y N e w Y e a r !

例2

String.concat関数は、指定された文字列のシーケンスをセパレータで連結し、新しい文字列を返します。

let strings = [ "Tutorials Point"; "Coding Ground"; "Absolute Classes" ]
let ourProducts = String.concat "\n" strings
printfn "%s" ourProducts

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Tutorials Point
Coding Ground
Absolute Classes

実施例3

String.replicateメソッドは、指定された数の文字列のインスタンスを連結して文字列を返します。

printfn "%s" <| String.replicate 10 "*! "

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

*! *! *! *! *! *! *! *! *! *!

F#-オプション

F#の option タイプは、変数または関数の値が存在する場合と存在しない場合の計算で使用されます。 オプションタイプは、計算でオプション値を表すために使用されます。 * Some(x)または *None の2つの値を設定できます。

たとえば、除算を実行する関数は、通常の状況では値を返しますが、分母がゼロの場合は例外をスローします。 ここでオプションを使用すると、関数が成功したか失敗したかを示すのに役立ちます。

オプションには基礎となるタイプがあり、そのタイプの値を保持できますが、値がない場合もあります。

オプションを使用する

除算関数の例を見てみましょう。 次のプログラムはこれを説明します-

関数divを書いて、20と5に2つの引数を送りましょう-

let div x y = x/y
let res = div 20 5
printfn "Result: %d" res

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Result: 4

2番目の引数がゼロの場合、プログラムは例外をスローします-

let div x y = x/y
let res = div 20 0
printfn "Result: %d" res

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Unhandled Exception:
System.DivideByZeroException: Division by zero

このような場合、オプションタイプを使用して、操作が成功した場合はSome(値)を返し、操作が失敗した場合はNoneを返すことができます。

次の例は、オプションの使用を示しています-

let div x y =
   match y with
   | 0 -> None
   | _ -> Some(x/y)

let res : int option = div 20 4
printfn "Result: %A " res

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Result: Some 5

オプションのプロパティとメソッド

オプションタイプは、次のプロパティとメソッドをサポートしています-

Property or method Type Description
None 'T option A static property that enables you to create an option value that has the None value.
IsNone bool Returns true *if the option has the None *value.
IsSome bool Returns* true if the option has a value that is not None*.
Some 'T option A static member that creates an option that has a value that is not None.
Value 'T Returns the underlying value, or throws a NullReferenceException if the value is None.

例1

let checkPositive (a : int) =
   if a > 0 then
      Some(a)
   else
      None

let res : int option = checkPositive(-31)
printfn "Result: %A " res

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Result: <null>

例2

let div x y =
   match y with
   | 0 -> None
   | _ -> Some(x/y)

let res : int option = div 20 4
printfn "Result: %A " res
printfn "Result: %A " res.Value

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Result: Some 5
Result: 5

実施例3

let isHundred = function
   | Some(100) -> true
   | Some(_) | None -> false

printfn "%A" (isHundred (Some(45)))
printfn "%A" (isHundred (Some(100)))
printfn "%A" (isHundred None)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

false
true
false

F#-タプル

*tuple* は、コンマで区切られた値のコレクションです。 これらは、関連する値をグループ化するアドホックデータ構造の作成に使用されます。

たとえば、(“ Zara Ali”、“ Hyderabad”、10)は、2つの文字列値とint値を持つ3タプルであり、タイプ(string string int)を持ちます。

タプルは、同じタイプまたは異なるタイプのペア、トリプルなどです。

ここにいくつかの例を示します-

//Tuple of two integers.
( 4, 5 )

//Triple of strings.
( "one", "two", "three" )

//Tuple of unknown types.
( a, b )

//Tuple that has mixed types.
( "Absolute Classes", 1, 2.0 )

//Tuple of integer expressions.
( a * 4, b + 7)

このプログラムは、4つの浮動小数点値のタプルを取り、平均を返す関数を持っています-

let averageFour (a, b, c, d) =
   let sum = a + b + c + d
   sum/4.0

let avg:float = averageFour (4.0, 5.1, 8.0, 12.0)
printfn "Avg of four numbers: %f" avg

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Avg of four numbers: 7.275000

個々のタプルメンバーへのアクセス

タプルの個々のメンバーは、パターンマッチングを使用して評価および印刷できます。

次の例は、概念を示しています-

let display tuple1 =
   match tuple1 with
   | (a, b, c) -> printfn "Detail Info: %A %A %A" a b c

display ("Zara Ali", "Hyderabad", 10 )

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Detail Info: "Zara Ali" "Hyderabad" 10

F#には2つの組み込み関数、 fst および* snd、*があり、2タプルの最初と2番目の項目を返します。

次の例は、概念を示しています-

printfn "First member: %A" (fst(23, 30))
printfn "Second member: %A" (snd(23, 30))

printfn "First member: %A" (fst("Hello", "World!"))
printfn "Second member: %A" (snd("Hello", "World!"))

let nameTuple = ("Zara", "Ali")

printfn "First Name: %A" (fst nameTuple)
printfn "Second Name: %A" (snd nameTuple)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

First member: 23
Second member: 30
First member: "Hello"
Second member: "World!"
First Name: "Zara"
Second Name: "Ali"

F#-レコード

  • レコード*はタプルに似ていますが、名前付きフィールドが含まれています。 例えば、
type website =
   { title : string;
     url : string }

レコードの定義

レコードは type キーワードを使用してタイプとして定義され、レコードのフィールドはセミコロンで区切られたリストとして定義されます。

レコードを定義するための構文は-

type recordName =
   { [ fieldName : dataType ] + }

レコードを作成する

レコードのフィールドを指定して、レコードを作成できます。 たとえば、_homepage_という名前の_website_レコードを作成します-

let homepage = { Title = "finddevguides"; Url = "www.finddevguides.com" }

次の例では、概念を説明します-

例1

このプログラムは、websiteという名前のレコードタイプを定義します。 次に、Webサイトタイプのレコードを作成し、そのレコードを印刷します。

( *defining a record type named website* )
type website =
   { Title : string;
      Url : string }

( *creating some records* )
let homepage = { Title = "finddevguides"; Url = "www.finddevguides.com" }
let cpage = { Title = "Learn C"; Url = "www.finddevguides.com/cprogramming/index" }
let fsharppage = { Title = "Learn F#"; Url = "www.finddevguides.com/fsharp/index" }
let csharppage = { Title = "Learn C#"; Url = "www.finddevguides.com/csharp/index" }

(*printing records *)
(printfn "Home Page: Title: %A \n \t URL: %A") homepage.Title homepage.Url
(printfn "C Page: Title: %A \n \t URL: %A") cpage.Title cpage.Url
(printfn "F# Page: Title: %A \n \t URL: %A") fsharppage.Title fsharppage.Url
(printfn "C# Page: Title: %A \n \t URL: %A") csharppage.Title csharppage.Url

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Home Page: Title: "finddevguides"
       URL: "www.finddevguides.com"
C Page: Title: "Learn C"
      URL: "www.finddevguides.com/cprogramming/index"
F# Page: Title: "Learn F#"
      URL: "www.finddevguides.com/fsharp/index"
C# Page: Title: "Learn C#"
      URL: "www.finddevguides.com/csharp/index"

例2

type student =
   { Name : string;
      ID : int;
      RegistrationText : string;
      IsRegistered : bool }

let getStudent name id =
   { Name = name; ID = id; RegistrationText = null; IsRegistered = false }

let registerStudent st =
   { st with
      RegistrationText = "Registered";
      IsRegistered = true }

let printStudent msg st =
   printfn "%s: %A" msg st

let main() =
   let preRegisteredStudent = getStudent "Zara" 10
   let postRegisteredStudent = registerStudent preRegisteredStudent

   printStudent "Before Registration: " preRegisteredStudent
   printStudent "After Registration: " postRegisteredStudent

main()

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Before Registration: : {Name = "Zara";
   ID = 10;
   RegistrationText = null;
   IsRegistered = false;}
After Registration: : {Name = "Zara";
   ID = 10;
   RegistrationText = "Registered";
   IsRegistered = true;}

F#-リスト

F#では、リストは同じタイプの要素の順序付けられた不変のシリーズです。 これは、リンクリストのデータ構造とある程度同等です。

F#モジュール Microsoft.FSharp.Collections.List には、リストに対する一般的な操作があります。 ただし、F#はこのモジュールを自動的にインポートし、すべてのF#アプリケーションからアクセスできるようにします。

リストの作成と初期化

以下は、リストを作成するさまざまな方法です-

  • リスト literals を使用します。
  • cons (::)演算子を使用します。
  • Listモジュールの List.init メソッドを使用します。
  • List Comprehensions と呼ばれる*構文構文を使用します。

リテラルのリスト

この方法では、セミコロンで区切られた一連の値を角かっこで指定するだけです。 たとえば-

let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]

短所(::)演算子

このメソッドを使用すると、::演算子を使用して既存のリストに値を追加または cons-ing することにより、いくつかの値を追加できます。 たとえば-

let list2 = 1::2::3::4::5::6::7::8::9::10::[];;

[] denotes an empty list.

リストinitメソッド

ListモジュールのList.initメソッドは、リストの作成によく使用されます。 このメソッドには、タイプがあります-

val init : int -> (int -> 'T) -> 'T list

最初の引数は新しいリストに必要な長さで、2番目の引数は初期化関数で、リスト内のアイテムを生成します。

例えば、

let list5 = List.init 5 (fun index -> (index, index *index, index* index *index))

ここでは、インデックス関数がリストを生成します。

リスト内包表記

リストの内包表記は、リストの生成に使用される特別な構文構造です。

F#リスト内包構文には、範囲とジェネレータの2つの形式があります。

範囲には構造があります-[start .. end]および[start .. ステップ.. end]

例えば、

let list3 = [1 .. 10]

ジェネレータには構造があります-[コレクション内のxに対して…​ yield expr]

例えば、

let list6 = [ for a in 1 .. 10 do yield (a* a) ]
*yield* キーワードは単一の値をリストにプッシュするため、キーワード* yield!、*は値のコレクションをリストにプッシュします。

次の機能は、上記の方法を示しています-

( *using list literals* )
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1

(*using cons operator *)
let list2 = 1 :: 2 :: 3 :: []
printfn "The list: %A" list2

(* using range constructs*)
let list3 = [1 .. 10]
printfn "The list: %A" list3

( *using range constructs* )
let list4 = ['a' .. 'm']
printfn "The list: %A" list4

( *using init method* )
let list5 = List.init 5 (fun index -> (index, index *index, index* index * index))
printfn "The list: %A" list5

( *using yield operator* )
let list6 = [ for a in 1 .. 10 do yield (a * a) ]
printfn "The list: %A" list6

( *using yield operator* )
let list7 = [ for a in 1 .. 100 do if a % 3 = 0 && a % 5 = 0 then yield a]
printfn "The list: %A" list7

( *using yield! operator* )
let list8 = [for a in 1 .. 3 do yield! [ a .. a + 3 ] ]
printfn "The list: %A" list8

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: [1; 2; 3]
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: ['a'; 'b'; 'c'; 'd'; 'e'; 'f'; 'g'; 'h'; 'i'; 'j'; 'k'; 'l'; 'm']
The list: [(0, 0, 0); (1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64)]
The list: [1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
The list: [15; 30; 45; 60; 75; 90]
The list: [1; 2; 3; 4; 2; 3; 4; 5; 3; 4; 5; 6]

リストデータ型のプロパティ

次の表は、リストのデータ型のさまざまなプロパティを示しています-

Property Type Description
Head 'T The first element.
Empty 'T list A static property that returns an empty list of the appropriate type.
IsEmpty bool *true *if the list has no elements.
Item 'T The element at the specified index (zero-based).
Length int The number of elements.
Tail 'T list The list without the first element.

次の例は、これらのプロパティの使用を示しています-

let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]

//Use of Properties
printfn "list1.IsEmpty is %b" (list1.IsEmpty)
printfn "list1.Length is %d" (list1.Length)
printfn "list1.Head is %d" (list1.Head)
printfn "list1.Tail.Head is %d" (list1.Tail.Head)
printfn "list1.Tail.Tail.Head is %d" (list1.Tail.Tail.Head)
printfn "list1.Item(1) is %d" (list1.Item(1))

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

list1.IsEmpty is false
list1.Length is 8
list1.Head is 2
list1.Tail.Head is 4
list1.Tail.Tail.Head is 6
list1.Item(1) is 4

リストの基本的な演算子

次の表は、リストのデータ型の基本的な操作を示しています-

Value Description
append : 'T list → 'T list → 'T list Returns a new list that contains the elements of the first list followed by elements of the second.
average : 'T list → ^T Returns the average of the elements in the list.
averageBy : ('T → ^U) → 'T list → ^U Returns the average of the elements generated by applying the function to each element of the list.
choose : ('T → 'U option) → 'T list → 'U list Applies the given function to each element of the list. Returns the list comprised of the results for each element where the function returns* Some*.
collect : ('T → 'U list) → 'T list → 'U list For each element of the list, applies the given function. Concatenates all the results and return the combined list.
concat : seq<'T list> → 'T list Returns a new list that contains the elements of each the lists in order.
empty : 'T list Returns an empty list of the given type.
exists : ('T → bool) → 'T list → bool Tests if any element of the list satisfies the given predicate.
exists2 : ('T1 → 'T2 → bool) → 'T1 list → 'T2 list → bool Tests if any pair of corresponding elements of the lists satisfies the given predicate.
filter : ('T → bool) → 'T list → 'T list Returns a new collection containing only the elements of the collection for which the given predicate returns true.
find : ('T → bool) → 'T list → 'T Returns the first element for which the given function returns true.
findIndex : ('T → bool) → 'T list → int Returns the index of the first element in the list that satisfies the given predicate.
fold : ('State → 'T → 'State) → 'State → 'T list → 'State Applies a function to each element of the collection, threading an accumulator argument through the computation. This function takes the second argument, and applies the function to it and the first element of the list. Then, it passes this result into the function along with the second element, and so on. Finally, it returns the final result. If the input function is f and the elements are i0…​iN, then this function computes f (…​ (f s i0) i1 …​) iN.
fold2 : ('State → 'T1 → 'T2 → 'State) → 'State → 'T1 list → 'T2 list → 'State Applies a function to corresponding elements of two collections, threading an accumulator argument through the computation. The collections must have identical sizes. If the input function is f and the elements are i0…​iN and j0…​jN, then this function computes f (…​ (f s i0 j0)…​) iN jN.
foldBack : ('T → 'State → 'State) → 'T list → 'State → 'State Applies a function to each element of the collection, threading an accumulator argument through the computation. If the input function isf and the elements are i0…​iN then computes f i0 (…​(f iN s)).
foldBack2 : ('T1 → 'T2 → 'State → 'State) → 'T1 list → 'T2 list → 'State → 'State Applies a function to corresponding elements of two collections, threading an accumulator argument through the computation. The collections must have identical sizes. If the input function is f and the elements are i0…​iN and j0…​jN, then this function computes f i0 j0 (…​(f iN jN s)).
forall : ('T → bool) → 'T list → bool Tests if all elements of the collection satisfy the given predicate.
forall2 : ('T1 → 'T2 → bool) → 'T1 list → 'T2 list → bool Tests if all corresponding elements of the collection satisfy the given predicate pairwise.
head : 'T list → 'T Returns the first element of the list.
init : int → (int → 'T) → 'T list Creates a list by calling the given generator on each index.
isEmpty : 'T list → bool Returns true *if the list contains no elements, false *otherwise.
iter : ('T → unit) → 'T list → unit Applies the given function to each element of the collection.
iter2 : ('T1 → 'T2 → unit) → 'T1 list → 'T2 list → unit Applies the given function to two collections simultaneously. The collections must have identical size.
iteri : (int → 'T → unit) → 'T list → unit Applies the given function to each element of the collection. The integer passed to the function indicates the index of element.
iteri2 : (int → 'T1 → 'T2 → unit) → 'T1 list → 'T2 list → unit Applies the given function to two collections simultaneously. The collections must have identical size. The integer passed to the function indicates the index of element.
length : 'T list → int Returns the length of the list.
map : ('T → 'U) → 'T list → 'U list Creates a new collection whose elements are the results of applying the given function to each of the elements of the collection.
map2 : ('T1 → 'T2 → 'U) → 'T1 list → 'T2 list → 'U list Creates a new collection whose elements are the results of applying the given function to the corresponding elements of the two collections pairwise.
map3 : ('T1 → 'T2 → 'T3 → 'U) → 'T1 list → 'T2 list → 'T3 list → 'U list Creates a new collection whose elements are the results of applying the given function to the corresponding elements of the three collections simultaneously.
mapi : (int → 'T → 'U) → 'T list → 'U list Creates a new collection whose elements are the results of applying the given function to each of the elements of the collection. The integer index passed to the function indicates the index (from 0) of element being transformed.
mapi2 : (int → 'T1 → 'T2 → 'U) → 'T1 list → 'T2 list → 'U list Like List.mapi, but mapping corresponding elements from two lists of equal length.
max : 'T list → 'T Returns the greatest of all elements of the list, compared by using Operators.max.
maxBy : ('T → 'U) → 'T list → 'T Returns the greatest of all elements of the list, compared by using Operators.max on the function result.
min : 'T list → 'T Returns the lowest of all elements of the list, compared by using Operators.min.
minBy : ('T → 'U) → 'T list → 'T Returns the lowest of all elements of the list, compared by using Operators.min on the function result
nth : 'T list → int → 'T Indexes into the list. The first element has index 0.
ofArray : 'T [] → 'T list Creates a list from the given array.
ofSeq : seq<'T> → 'T list Creates a new list from the given enumerable object.
partition : ('T → bool) → 'T list* 'T list Splits the collection into two collections, containing the elements for which the given predicate returns true *and false *respectively.
permute : (int → int) → 'T list → 'T list Returns a list with all elements permuted according to the specified permutation.
pick : ('T → 'U option) → 'T list → 'U Applies the given function to successive elements, returning the first result where function returns* Some *for some value.
reduce : ('T → 'T → 'T) → 'T list → 'T Applies a function to each element of the collection, threading an accumulator argument through the computation. This function applies the specified function to the first two elements of the list. It then passes this result into the function along with the third element, and so on. Finally, it returns the final result. If the input function is f and the elements are i0…​iN, then this function computes f (…​ (f i0 i1) i2 …​) iN.
reduceBack : ('T → 'T → 'T) → 'T list → 'T Applies a function to each element of the collection, threading an accumulator argument through the computation. If the input function isf and the elements are i0…​iN, then this function computes f i0 (…​(f iN-1 iN)).
replicate : (int → 'T → 'T list) Creates a list by calling the given generator on each index.
rev : 'T list → 'T list Returns a new list with the elements in reverse order.
scan : ('State → 'T → 'State) → 'State → 'T list → 'State list Applies a function to each element of the collection, threading an accumulator argument through the computation. This function takes the second argument, and applies the specified function to it and the first element of the list. Then, it passes this result into the function along with the second element and so on. Finally, it returns the list of intermediate results and the final result.
scanBack : ('T → 'State → 'State) → 'T list → 'State → 'State list Like foldBack, but returns both the intermediate and final results
sort : 'T list → 'T list Sorts the given list using Operators.compare.
sortBy : ('T → 'Key) → 'T list → 'T list Sorts the given list using keys given by the given projection. Keys are compared using Operators.compare.
sortWith : ('T → 'T → int) → 'T list → 'T list Sorts the given list using the given comparison function.
sum : ^T list → ^T Returns the sum of the elements in the list.
sumBy : ('T → ^U) → 'T list → ^U Returns the sum of the results generated by applying the function to each element of the list.
tail : 'T list → 'T list Returns the input list without the first element.
toArray : 'T list → 'T [] Creates an array from the given list.
toSeq : 'T list → seq<'T> Views the given list as a sequence.
tryFind : ('T → bool) → 'T list → 'T option Returns the first element for which the given function returns* true*. Return *None *if no such element exists.
tryFindIndex : ('T → bool) → 'T list → int option Returns the index of the first element in the list that satisfies the given predicate. Return* None *if no such element exists.
tryPick : ('T → 'U option) → 'T list → 'U option Applies the given function to successive elements, returning the first result where function returns* Some for some value. If no such element exists then return None*.
unzip : ('T1 'T2) list → 'T1 list 'T2 list Splits a list of pairs into two lists.
unzip3 : ('T1 'T2 'T3) list → 'T1 list 'T2 list 'T3 list Splits a list of triples into three lists.
zip : 'T1 list → 'T2 list → ('T1 *'T2) list Combines the two lists into a list of pairs. The two lists must have equal lengths.
zip3 : 'T1 list → 'T2 list → 'T3 list → ('T1* 'T2 * 'T3) list Combines the three lists into a list of triples. The lists must have equal lengths.

次の例は、上記の機能の使用方法を示しています-

例1

このプログラムは、リストを再帰的に逆にすることを示しています-

let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1

let reverse lt =
   let rec loop acc = function
      | [] -> acc
      | hd :: tl -> loop (hd :: acc) tl
   loop [] lt

printfn "The reversed list: %A" (reverse list1)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]

ただし、同じ目的でモジュールの rev 関数を使用できます-

let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
printfn "The reversed list: %A" (List.rev list1)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]

例2

このプログラムは、 List.filter メソッドを使用してリストをフィルタリングすることを示しています-

let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.filter (fun x -> x % 2 = 0);;
printfn "The Filtered list: %A" list2

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Filtered list: [2; 4; 6; 8; 10]

実施例3

*List.map* メソッドは、リストをあるタイプから別のタイプにマップします-
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.map (fun x -> (x * x).ToString());;
printfn "The Mapped list: %A" list2

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Mapped list: ["1"; "4"; "9"; "16"; "25"; "36"; "49"; "64"; "81"; "100"]

実施例4

*List.append* メソッドと@演算子は、あるリストを別のリストに追加します-
let list1 = [1; 2; 3; 4; 5 ]
let list2 = [6; 7; 8; 9; 10]
let list3 = List.append list1 list2

printfn "The first list: %A" list1
printfn "The second list: %A" list2
printfn "The appened list: %A" list3

let lt1 = ['a'; 'b';'c' ]
let lt2 = ['e'; 'f';'g' ]
let lt3 = lt1 @ lt2

printfn "The first list: %A" lt1
printfn "The second list: %A" lt2
printfn "The appened list: %A" lt3

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The first list: [1; 2; 3; 4; 5]
The second list: [6; 7; 8; 9; 10]
The appened list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The first list: ['a'; 'b'; 'c']
The second list: ['e'; 'f'; 'g']
The appened list: ['a'; 'b'; 'c'; 'e'; 'f'; 'g']

実施例5

*List.sort* メソッドはリストをソートします。 *List.sum* メソッドは、リスト内の要素の合計を提供し、 *List.average* メソッドは、リスト内の要素の平均を提供します-
let list1 = [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
printfn "The list: %A" list1

let list2 = List.sort list1
printfn "The sorted list: %A" list2

let s = List.sum list1
let avg = List.average list1
printfn "The sum: %f" s
printfn "The average: %f" avg

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The list: [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
The sorted list: [-10.0; -4.5; 0.0; 2.0; 8.0; 9.0; 11.2]
The sum: 15.700000
The average: 2.242857

「fold」操作は、リスト内の各要素に関数を適用し、関数の結果をアキュムレーター変数に集約し、フォールド操作の結果としてアキュムレーターを返します。

実施例6

*List.fold* メソッドは各要素に左から右に関数を適用し、 *List.foldBack* は関数を右から左に各要素に適用します。
let sumList list = List.fold (fun acc elem -> acc + elem) 0 list
printfn "Sum of the elements of list %A is %d." [ 1 .. 10 ] (sumList [ 1 .. 10 ])

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Sum of the elements of list [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] is 55.

F#-シーケンス

リストのようなシーケンスも、値の順序付けられたコレクションを表します。 ただし、シーケンスまたはシーケンス式の要素は、必要なときに計算されます。 これらは一度に計算されないため、無限のデータ構造を表すために使用されます。

シーケンスの定義

シーケンスは、次の構文を使用して定義されます-

seq { expr }

例えば、

let seq1 = seq { 1 .. 10 }

シーケンスとシーケンス式の作成

リストと同様に、範囲と内包表記を使用してシーケンスを作成できます。

シーケンス式は、シーケンスを作成するために作成できる式です。 これらを行うことができます-

  • 範囲を指定します。
  • インクリメントまたはデクリメントで範囲を指定します。
  • yield キーワードを使用して、シーケンスの一部となる値を生成します。
  • →演算子を使用します。

次の例は、概念を示しています-

例1

( *Sequences* )
let seq1 = seq { 1 .. 10 }

(* ascending order and increment*)
printfn "The Sequence: %A" seq1
let seq2 = seq { 1 .. 5 .. 50 }

(* descending order and decrement*)
printfn "The Sequence: %A" seq2

let seq3 = seq {50 .. -5 .. 0}
printfn "The Sequence: %A" seq3

( *using yield* )
let seq4 = seq { for a in 1 .. 10 do yield a, a*a, a*a*a }
printfn "The Sequence: %A" seq4

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The Sequence: seq [1; 2; 3; 4; ...]
The Sequence: seq [1; 6; 11; 16; ...]
The Sequence: seq [50; 45; 40; 35; ...]
The Sequence: seq [(1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64); ...]

例2

次のプログラムは、1から50までの素数を印刷します-

( *Recursive isprime function.* )
let isprime n =
   let rec check i =
      i > n/2 || (n % i <> 0 && check (i + 1))
   check 2

let primeIn50 = seq { for n in 1..50 do if isprime n then yield n }
for x in primeIn50 do
   printfn "%d" x

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

1
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47

シーケンスの基本操作

次の表は、シーケンスデータ型の基本的な操作を示しています-

Value Description
append : seq<'T> → seq<'T> → seq<'T> Wraps the two given enumerations as a single concatenated enumeration.
average : seq<^T> → ^T Returns the average of the elements in the sequence.
averageBy : ('T → ^U) → seq<'T> → ^U Returns the average of the results generated by applying the function to each element of the sequence.
cache : seq<'T> → seq<'T> Returns a sequence that corresponds to a cached version of the input sequence.
cast : IEnumerable → seq<'T> Wraps a loosely-typed System. Collections sequence as a typed sequence.
choose : ('T → 'U option) → seq<'T> → seq<'U> Applies the given function to each element of the list. Return the list comprised of the results for each element where the function returns Some.
collect : ('T → 'Collection) → seq<'T> → seq<'U> Applies the given function to each element of the sequence and concatenates all the results.
compareWith : ('T → 'T → int) → seq<'T> → seq<'T> → int Compares two sequences using the given comparison function, element by element.
concat : seq<'Collection> → seq<'T> Combines the given enumeration-of-enumerations as a single concatenated enumeration.
countBy : ('T → 'Key) → seq<'T> → seq<'Key *int> Applies a key-generating function to each element of a sequence and return a sequence yielding unique keys and their number of occurrences in the original sequence.
delay : (unit → seq<'T>) → seq<'T> Returns a sequence that is built from the given delayed specification of a sequence.
distinct : seq<'T> → seq<'T> Returns a sequence that contains no duplicate entries according to generic hash and equality comparisons on the entries. If an element occurs multiple times in the sequence then the later occurrences are discarded.
distinctBy : ('T → 'Key) → seq<'T> → seq<'T> Returns a sequence that contains no duplicate entries according to the generic hash and equality comparisons on the keys returned by the given key-generating function. If an element occurs multiple times in the sequence then the later occurrences are discarded.
empty : seq<'T> Creates an empty sequence.
exactlyOne : seq<'T> → 'T Returns the only element of the sequence.
exists : ('T → bool) → seq<'T> → bool Tests if any element of the sequence satisfies the given predicate.
exists2 : ('T1 → 'T2 → bool) → seq<'T1> → seq<'T2> → bool Tests if any pair of corresponding elements of the input sequences satisfies the given predicate.
filter : ('T → bool) → seq<'T> → seq<'T> Returns a new collection containing only the elements of the collection for which the given predicate returns* true*.
find : ('T → bool) → seq<'T> → 'T Returns the first element for which the given function returns true.
findIndex : ('T → bool) → seq<'T> → int Returns the index of the first element for which the given function returns true.
fold : ('State → 'T → 'State) → 'State → seq<'T> → 'State Applies a function to each element of the collection, threading an accumulator argument through the computation. If the input function is f and the elements are i0…​iN, then this function computes f (…​ (f s i0)…​) iN.
forall : ('T → bool) → seq<'T> → bool Tests if all elements of the sequence satisfy the given predicate.
forall2 : ('T1 → 'T2 → bool) → seq<'T1> → seq<'T2> → bool Tests the all pairs of elements drawn from the two sequences satisfy the given predicate. If one sequence is shorter than the other then the remaining elements of the longer sequence are ignored.
groupBy : ('T → 'Key) → seq<'T> → seq<'Key *seq<'T>> Applies a key-generating function to each element of a sequence and yields a sequence of unique keys. Each unique key has also contains a sequence of all elements that match to this key.
head : seq<'T> → 'T Returns the first element of the sequence.
init : int → (int → 'T) → seq<'T> Generates a new sequence which, when iterated, returns successive elements by calling the given function, up to the given count. The results of calling the function are not saved, that is, the function is reapplied as necessary to regenerate the elements. The function is passed the index of the item being generated.
initInfinite : (int → 'T) → seq<'T> Generates a new sequence which, when iterated, will return successive elements by calling the given function. The results of calling the function are not saved, that is, the function will be reapplied as necessary to regenerate the elements. The function is passed the index of the item being generated.
isEmpty : seq<'T> → bool Tests whether a sequence has any elements.
iter : ('T → unit) → seq<'T> → unit Applies the given function to each element of the collection.
iter2 : ('T1 → 'T2 → unit) → seq<'T1> → seq<'T2> → unit Applies the given function to two collections simultaneously. If one sequence is shorter than the other then the remaining elements of the longer sequence are ignored.
iteri : (int → 'T → unit) → seq<'T> → unit Applies the given function to each element of the collection. The integer passed to the function indicates the index of element.
last : seq<'T> → 'T Returns the last element of the sequence.
length : seq<'T> → int Returns the length of the sequence.
map : ('T → 'U) → seq<'T> → seq<'U> Creates a new collection whose elements are the results of applying the given function to each of the elements of the collection. The given function will be applied as elements are demanded using the MoveNext method on enumerators retrieved from the object.
map2 : ('T1 → 'T2 → 'U) → seq<'T1> → seq<'T2> → seq<'U> Creates a new collection whose elements are the results of applying the given function to the corresponding pairs of elements from the two sequences. If one input sequence is shorter than the other then the remaining elements of the longer sequence are ignored.
mapi : (int → 'T → 'U) → seq<'T> → seq<'U> Creates a new collection whose elements are the results of applying the given function to each of the elements of the collection. The integer index passed to the function indicates the index (from 0) of element being transformed.
max : seq<'T> → 'T Returns the greatest of all elements of the sequence, compared by using Operators.max.
maxBy : ('T → 'U) → seq<'T> → 'T Returns the greatest of all elements of the sequence, compared by using Operators.max on the function result.
min : seq<'T> → 'T Returns the lowest of all elements of the sequence, compared by using Operators.min.
minBy : ('T → 'U) → seq<'T> → 'T Returns the lowest of all elements of the sequence, compared by using Operators.min on the function result.
nth : int → seq<'T> → 'T Computes the nth element in the collection.
ofArray : 'T array → seq<'T> Views the given array as a sequence.
ofList : 'T list → seq<'T> Views the given list as a sequence.
pairwise : seq<'T> → seq<'T* 'T> Returns a sequence of each element in the input sequence and its predecessor, with the exception of the first element which is only returned as the predecessor of the second element.
pick : ('T → 'U option) → seq<'T> → 'U Applies the given function to successive elements, returning the first value where the function returns a *Some *value.
readonly : seq<'T> → seq<'T> Creates a new sequence object that delegates to the given sequence object. This ensures the original sequence cannot be rediscovered and mutated by a type cast. For example, if given an array the returned sequence will return the elements of the array, but you cannot cast the returned sequence object to an array.
reduce : ('T → 'T → 'T) → seq<'T> → 'T Applies a function to each element of the sequence, threading an accumulator argument through the computation. Begin by applying the function to the first two elements. Then feed this result into the function along with the third element and so on. Return the final result.
scan : ('State → 'T → 'State) → 'State → seq<'T> → seq<'State> Like Seq.fold, but computes on-demand and returns the sequence of intermediary and final results.
singleton : 'T → seq<'T> Returns a sequence that yields one item only.
skip : int → seq<'T> → seq<'T> Returns a sequence that skips a specified number of elements of the underlying sequence and then yields the remaining elements of the sequence.
skipWhile : ('T → bool) → seq<'T> → seq<'T> Returns a sequence that, when iterated, skips elements of the underlying sequence while the given predicate returns* true, *and then yields the remaining elements of the sequence.
sort : seq<'T> → seq<'T> Yields a sequence ordered by keys.
sortBy : ('T → 'Key) → seq<'T> → seq<'T> Applies a key-generating function to each element of a sequence and yield a sequence ordered by keys. The keys are compared using generic comparison as implemented by Operators.compare.
sum : seq<^T> → ^T Returns the sum of the elements in the sequence.
sumBy Returns the sum of the results generated by applying the function to each element of the sequence.
take : int → seq<'T> → seq<'T> Returns the first elements of the sequence up to a specified count.
takeWhile : ('T → bool) → seq<'T> → seq<'T> Returns a sequence that, when iterated, yields elements of the underlying sequence while the given predicate returns* true, *and then returns no further elements.
toArray : seq<'T> → 'T[] Creates an array from the given collection.
toList : seq<'T> → 'T list Creates a list from the given collection.
truncate : int → seq<'T> → seq<'T> Returns a sequence that when enumerated returns no more than a specified number of elements.
tryFind : ('T → bool) → seq<'T> → 'T option Returns the first element for which the given function returns* true, or None *if no such element exists.
tryFindIndex : ('T → bool) → seq<'T> → int option Returns the index of the first element in the sequence that satisfies the given predicate, or* None *if no such element exists.
tryPick : ('T → 'U option) → seq<'T> → 'U option Applies the given function to successive elements, returning the first value where the function returns a* Some *value.
unfold : ('State → 'T* 'State option) → 'State → seq<'T> Returns a sequence that contains the elements generated by the given computation.
where : ('T → bool) → seq<'T> → seq<'T> Returns a new collection containing only the elements of the collection for which the given predicate returns true. A synonym for Seq.filter.
windowed : int → seq<'T> → seq<'T []> Returns a sequence that yields sliding windows of containing elements drawn from the input sequence. Each window is returned as a fresh array.
zip : seq<'T1> → seq<'T2> → seq<'T1 *'T2> Combines the two sequences into a list of pairs. The two sequences need not have equal lengths − when one sequence is exhausted any remaining elements in the other sequence are ignored.
zip3 : seq<'T1> → seq<'T2> → seq<'T3> → seq<'T1* 'T2 * 'T3> Combines the three sequences into a list of triples. The sequences need not have equal lengths − when one sequence is exhausted any remaining elements in the other sequences are ignored.

次の例は、上記の機能のいくつかの使用を示しています-

例1

このプログラムは、空のシーケンスを作成し、後でそれを埋めます-

( *Creating sequences* )
let emptySeq = Seq.empty
let seq1 = Seq.singleton 20

printfn"The singleton sequence:"
printfn "%A " seq1
printfn"The init sequence:"

let seq2 = Seq.init 5 (fun n -> n * 3)
Seq.iter (fun i -> printf "%d " i) seq2
printfn""

( *converting an array to sequence by using cast* )
printfn"The array sequence 1:"
let seq3 = [| 1 .. 10 |] :> seq<int>
Seq.iter (fun i -> printf "%d " i) seq3
printfn""

( *converting an array to sequence by using Seq.ofArray* )
printfn"The array sequence 2:"
let seq4 = [| 2..2.. 20 |] |> Seq.ofArray
Seq.iter (fun i -> printf "%d " i) seq4
printfn""

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The singleton sequence:
seq [20]
The init sequence:
0 3 6 9 12
The array sequence 1:
1 2 3 4 5 6 7 8 9 10
The array sequence 2:
2 4 6 8 10 12 14 16 18 20

次のことに注意してください-

  • Seq.emptyメソッドは、空のシーケンスを作成します。
  • Seq.singletonメソッドは、指定された1つの要素のみのシーケンスを作成します。
  • Seq.initメソッドは、特定の関数を使用して要素が作成されるシーケンスを作成します。
  • Seq.ofArrayおよびSeq.ofList <'T>メソッドは、配列およびリストからシーケンスを作成します。
  • Seq.iterメソッドを使用すると、シーケンスを反復処理できます。

例2

Seq.unfoldメソッドは、状態を取り、それを変換してシーケンス内の後続の各要素を生成する計算関数からシーケンスを生成します。

次の関数は、最初の20自然数を生成します-

let seq1 = Seq.unfold (fun state -> if (state > 20) then None else Some(state, state + 1)) 0
printfn "The sequence seq1 contains numbers from 0 to 20."
for x in seq1 do printf "%d " x
printfn" "

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The sequence seq1 contains numbers from 0 to 20.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

実施例3

Seq.truncateメソッドは、別のシーケンスからシーケンスを作成しますが、シーケンスを指定された要素数に制限します。

Seq.takeメソッドは、シーケンスの先頭から指定された数の要素を含む新しいシーケンスを作成します。

let mySeq = seq { for i in 1 .. 10 -> 3*i }
let truncatedSeq = Seq.truncate 5 mySeq
let takeSeq = Seq.take 5 mySeq

printfn"The original sequence"
Seq.iter (fun i -> printf "%d " i) mySeq
printfn""

printfn"The truncated sequence"
Seq.iter (fun i -> printf "%d " i) truncatedSeq
printfn""

printfn"The take sequence"
Seq.iter (fun i -> printf "%d " i) takeSeq
printfn""

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The original sequence
3 6 9 12 15 18 21 24 27 30
The truncated sequence
3 6 9 12 15
The take sequence
3 6 9 12 15

F#-セット

F#のセットは、アイテムが挿入される順序を保持せずにアイテムのコレクションとして機能するデータ構造です。 セットでは、コレクションに重複エントリを挿入できません。

セットを作成する

セットは、次の方法で作成することができます-

  • Set.emptyを使用して空のセットを作成し、add関数を使用してアイテムを追加します。
  • シーケンスとリストをセットに変換します。

次のプログラムは、テクニックを示しています-

( *creating sets* )
let set1 = Set.empty.Add(3).Add(5).Add(7). Add(9)
printfn"The new set: %A" set1

let weekdays = Set.ofList ["mon"; "tues"; "wed"; "thurs"; "fri"]
printfn "The list set: %A" weekdays

let set2 = Set.ofSeq [ 1 .. 2.. 10 ]
printfn "The sequence set: %A" set2

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The new set: set [3; 5; 7; 9]
The list set: set ["fri"; "mon"; "thurs"; "tues"; "wed"]
The sequence set: set [1; 3; 5; 7; 9]

セットの基本操作

次の表は、セットの基本的な操作を示しています-

Value Description
add : 'T → Set<'T> → Set<'T> Returns a new set with an element added to the set. No exception is raised if the set already contains the given element.
contains : 'T → Set<'T> → bool Evaluates to *true *if the given element is in the given set.
count : Set<'T> → int Returns the number of elements in the set.
difference : Set<'T> → Set<'T> → Set<'T> Returns a new set with the elements of the second set removed from the first.
empty : Set<'T> The empty set for the specified type.
exists : ('T → bool) → Set<'T> → bool Tests if any element of the collection satisfies the given predicate. If the input function is predicate and the elements are i0…​iN, then this function computes predicate i0 or …​ or predicate iN.
filter : ('T → bool) → Set<'T> → Set<'T> Returns a new collection containing only the elements of the collection for which the given predicate returns* true*.
fold : ('State → 'T → 'State) → 'State → Set<'T> → 'State Applies the given accumulating function to all the elements of the set.
foldBack : ('T → 'State → 'State) → Set<'T> → 'State → 'State Applies the given accumulating function to all the elements of the set.
forall : ('T → bool) → Set<'T> → bool Tests if all elements of the collection satisfy the given predicate. If the input function is p and the elements are i0…​iN, then this function computes p i0 && …​ && p iN.
intersect : Set<'T> → Set<'T> → Set<'T> Computes the intersection of the two sets.
intersectMany : seq<Set<'T>> → Set<'T> Computes the intersection of a sequence of sets. The sequence must be non-empty.
isEmpty : Set<'T> → bool Returns *true *if the set is empty.
isProperSubset : Set<'T> → Set<'T> → bool Evaluates to* true *if all elements of the first set are in the second, and at least one element of the second is not in the first.
isProperSuperset : Set<'T> → Set<'T> → bool Evaluates to* true *if all elements of the second set are in the first, and at least one element of the first is not in the second.
isSubset : Set<'T> → Set<'T> → bool Evaluates to* true *if all elements of the first set are in the second.
isSuperset : Set<'T> → Set<'T> → bool Evaluates to* true *if all elements of the second set are in the first.
iter : ('T → unit) → Set<'T> → unit Applies the given function to each element of the set, in order according to the comparison function.
map : ('T → 'U) → Set<'T> → Set<'U> Returns a new collection containing the results of applying the given function to each element of the input set.
maxElement : Set<'T> → 'T Returns the highest element in the set according to the ordering being used for the set.
minElement : Set<'T> → 'T Returns the lowest element in the set according to the ordering being used for the set.
ofArray : 'T array → Set<'T> Creates a set that contains the same elements as the given array.
ofList : 'T list → Set<'T> Creates a set that contains the same elements as the given list.
ofSeq : seq<'T> → Set<'T> Creates a new collection from the given enumerable object.
partition : ('T → bool) → Set<'T> → Set<'T>* Set<'T> Splits the set into two sets containing the elements for which the given predicate returns true and false respectively.
remove : 'T → Set<'T> → Set<'T> Returns a new set with the given element removed. No exception is raised if the set doesn’t contain the given element.
singleton : 'T → Set<'T> The set containing the given element.
toArray : Set<'T> → 'T array Creates an array that contains the elements of the set in order.
toList : Set<'T> → 'T list Creates a list that contains the elements of the set in order.
toSeq : Set<'T> → seq<'T> Returns an ordered view of the collection as an enumerable object.
union : Set<'T> → Set<'T> → Set<'T> Computes the union of the two sets.
unionMany : seq<Set<'T>> → Set<'T> Computes the union of a sequence of sets.

次の例は、上記の機能のいくつかの使用を示しています-

let a = Set.ofSeq [ 1 ..2.. 20 ]
let b = Set.ofSeq [ 1 ..3 .. 20 ]
let c = Set.intersect a b
let d = Set.union a b
let e = Set.difference a b

printfn "Set a: "
Set.iter (fun x -> printf "%O " x) a
printfn""

printfn "Set b: "
Set.iter (fun x -> printf "%O " x) b
printfn""

printfn "Set c = set intersect of a and b : "
Set.iter (fun x -> printf "%O " x) c
printfn""

printfn "Set d = set union of a and b : "
Set.iter (fun x -> printf "%O " x) d
printfn""

printfn "Set e = set difference of a and b : "
Set.iter (fun x -> printf "%O " x) e
printfn""

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Set a:
1 3 5 7 9 11 13 15 17 19
Set b:
1 4 7 10 13 16 19
Set c = set intersect of a and b :
1 7 13 19
Set d = set union of a and b :
1 3 4 5 7 9 10 11 13 15 16 17 19
Set e = set difference of a and b :
3 5 9 11 15 17

F#-マップ

F#では、マップは値をキーに関連付ける特別な種類のセットです。 マップは、セットが作成されるのと同様の方法で作成されます。

マップを作成する

Map.emptyを使用して空のマップを作成し、Add関数を使用してアイテムを追加すると、マップが作成されます。 次の例はこれを示しています-

( *Create an empty Map* )
let students =
   Map.empty. ( *Creating an empty Map* )
      Add("Zara Ali", "1501").
      Add("Rishita Gupta", "1502").
      Add("Robin Sahoo", "1503").
      Add("Gillian Megan", "1504");;
printfn "Map - students: %A" students

( *Convert a list to Map* )
let capitals =
   [ "Argentina", "Buenos Aires";
      "France ", "Paris";
      "Chili", "Santiago";
      "Malaysia", " Kuala Lumpur";
      "Switzerland", "Bern" ]
   |> Map.ofList;;
printfn "Map capitals : %A" capitals

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Map - students: map
[("Gillian Megan", "1504"); ("Rishita Gupta", "1502"); ("Robin Sahoo", "1503
");
("Zara Ali", "1501")]
Map capitals : map
[("Argentina", "Buenos Aires"); ("Chili", "Santiago"); ("France ", "Paris");
("Malaysia", " Kuala Lumpur"); ("Switzerland", "Bern")]

キーを使用して、マップ内の個々の要素にアクセスできます。

( *Create an empty Map* )
let students =
   Map.empty. ( *Creating an empty Map* )
      Add("Zara Ali", "1501").
      Add("Rishita Gupta", "1502").
      Add("Robin Sahoo", "1503").
      Add("Gillian Megan", "1504");;
printfn "Map - students: %A" students

(*Accessing an element using key *)
printfn "%A" students.["Zara Ali"]

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Map - students: map
[("Gillian Megan", "1504"); ("Rishita Gupta", "1502"); ("Robin Sahoo", "1503
");
("Zara Ali", "1501")]
"1501"

マップの基本操作

モジュール名を追加

次の表は、マップの基本操作を示しています-

Member Description
Add Returns a new map with the binding added to the given map.
ContainsKey Tests if an element is in the domain of the map.
Count The number of bindings in the map.
IsEmpty Returns true if there are no bindings in the map.
Item Lookup an element in the map. Raises KeyNotFoundException if no binding exists in the map.
Remove Removes an element from the domain of the map. No exception is raised if the element is not present.
TryFind Lookup an element in the map, returning a Some *value if the element is in the domain of the map and None* if not.

次の例は、上記の機能のいくつかの使用を示しています-

( *Create an empty Map* )
let students =
   Map.empty. ( *Creating an empty Map* )
      Add("Zara Ali", "1501").
      Add("Rishita Gupta", "1502").
      Add("Robin Sahoo", "1503").
      Add("Gillian Megan", "1504").
      Add("Shraddha Dubey", "1505").
      Add("Novonil Sarker", "1506").
      Add("Joan Paul", "1507");;
printfn "Map - students: %A" students
printfn "Map - number of students: %d" students.Count

(* finding the registration number of a student*)
let found = students.TryFind "Rishita Gupta"
match found with
| Some x -> printfn "Found %s." x
| None -> printfn "Did not find the specified value."

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Map - students: map
[("Gillian Megan", "1504"); ("Joan Paul", "1507"); ("Novonil Sarker", "1506"
);
("Rishita Gupta", "1502"); ("Robin Sahoo", "1503");
("Shraddha Dubey", "1505"); ("Zara Ali", "1501")]
Map - number of students: 7
Found 1502.

F#-差別された組合

ユニオン、または差別化されたユニオンにより、明確に定義された選択肢セットを表す複雑なデータ構造を構築できます。 たとえば、yesとnoの2つの値を持つ_choice_変数の実装を構築する必要があります。 Unionsツールを使用して、これを設計できます。

構文

差別化された労働組合は、次の構文を使用して定義されています-

type type-name =
   | case-identifier1 [of [ fieldname1 : ] type1 [ *[ fieldname2 : ]
type2 ...]
   | case-identifier2 [of [fieldname3 : ]type3 [* [ fieldname4 : ]type4 ...]
...

、_choice、_の簡単な実装は次のようになります-

type choice =
   | Yes
   | No

次の例では、タイプの選択を使用します-

type choice =
   | Yes
   | No

let x = Yes ( *creates an instance of choice* )
let y = No ( *creates another instance of choice* )
let main() =
   printfn "x: %A" x
   printfn "y: %A" y
main()

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

x: Yes
y: No

例1

次の例は、高または低にビットを設定する電圧状態の実装を示しています-

type VoltageState =
   | High
   | Low

let toggleSwitch = function ( *pattern matching input* )
   | High -> Low
   | Low -> High

let main() =
   let on = High
   let off = Low
   let change = toggleSwitch off

   printfn "Switch on state: %A" on
   printfn "Switch off state: %A" off
   printfn "Toggle off: %A" change
   printfn "Toggle the Changed state: %A" (toggleSwitch change)

main()

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Switch on state: High
Switch off state: Low
Toggle off: High
Toggle the Changed state: Low

例2

type Shape =
  //here we store the radius of a circle
   | Circle of float

  //here we store the side length.
   | Square of float

  //here we store the height and width.
   | Rectangle of float *float

let pi = 3.141592654

let area myShape =
   match myShape with
   | Circle radius -> pi* radius *radius
   | Square s -> s* s
   | Rectangle (h, w) -> h * w

let radius = 12.0
let myCircle = Circle(radius)
printfn "Area of circle with radius %g: %g" radius (area myCircle)

let side = 15.0
let mySquare = Square(side)
printfn "Area of square that has side %g: %g" side (area mySquare)

let height, width = 5.0, 8.0
let myRectangle = Rectangle(height, width)
printfn "Area of rectangle with height %g and width %g is %g" height width (area myRectangle)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Area of circle with radius 12: 452.389
Area of square that has side 15: 225
Area of rectangle with height 5 and width 8 is 40

F#-可変データ

F#の変数は*不変*です。つまり、変数が値にバインドされると、変更することはできません。 実際には、静的な読み取り専用プロパティとしてコンパイルされます。

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

let x = 10
let y = 20
let z = x + y

printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

let x = 15
let y = 20
let z = x + y

printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

あなたがプログラムをコンパイルして実行すると、次のエラーメッセージが表示されます-

Duplicate definition of value 'x'
Duplicate definition of value 'Y'
Duplicate definition of value 'Z'

可変変数

時々、変数に保存されている値を変更する必要があります。 プログラムの後半で宣言および割り当てられた変数の値が変更される可能性があることを指定するために、F#には mutable キーワードが用意されています。 値を変更するこのキーワードを使用して、可変変数を宣言および割り当てることができます。

*mutable* キーワードを使用すると、可変変数で値を宣言して割り当てることができます。
*let* キーワードを使用して、可変変数に初期値を割り当てることができます。 ただし、新しい後続の値をそれに割り当てるには、* <-*演算子を使用する必要があります。

例えば、

let mutable x = 10
x <- 15

次の例は、概念をクリアします-

let mutable x = 10
let y = 20
let mutable z = x + y

printfn "Original Values:"
printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

printfn "Let us change the value of x"
printfn "Value of z will change too."

x <- 15
z <- x + y

printfn "New Values:"
printfn "x: %i" x
printfn "y: %i" y
printfn "z: %i" z

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Original Values:
x: 10
y: 20
z: 30
Let us change the value of x
Value of z will change too.
New Values:
x: 15
y: 20
z: 35

可変データの使用

多くの場合、特にレコードデータ構造の場合、データ処理で可変デー​​タが必要であり、使用されます。 次の例はこれを示しています-

open System

type studentData =
   { ID : int;
      mutable IsRegistered : bool;
      mutable RegisteredText : string; }

let getStudent id =
   { ID = id;
      IsRegistered = false;
      RegisteredText = null; }

let registerStudents (students : studentData list) =
   students |> List.iter(fun st ->
      st.IsRegistered <- true
      st.RegisteredText <- sprintf "Registered %s" (DateTime.Now.ToString("hh:mm:ss"))

      Threading.Thread.Sleep(1000) ( *Putting thread to sleep for 1 second to simulate processing overhead.* ))

let printData (students : studentData list) =
   students |> List.iter (fun x -> printfn "%A" x)

let main() =
   let students = List.init 3 getStudent

   printfn "Before Process:"
   printData students

   printfn "After process:"
   registerStudents students
   printData students

   Console.ReadKey(true) |> ignore

main()

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Before Process:
{ID = 0;
IsRegistered = false;
RegisteredText = null;}
{ID = 1;
IsRegistered = false;
RegisteredText = null;}
{ID = 2;
IsRegistered = false;
RegisteredText = null;}
After process:
{ID = 0;
IsRegistered = true;
RegisteredText = "Registered 05:39:15";}
{ID = 1;
IsRegistered = true;
RegisteredText = "Registered 05:39:16";}
{ID = 2;
IsRegistered = true;
RegisteredText = "Registered 05:39:17";}

F#-配列

配列は、すべて同じ型である連続したデータ要素の固定サイズのゼロベースの可変コレクションです。

配列の作成

さまざまな構文と方法を使用して、またはArrayモジュールの関数を使用して、配列を作成できます。 このセクションでは、モジュール関数を使用せずに配列を作成する方法について説明します。

関数なしで配列を作成する3つの構文的な方法があります-

  • [|および|]セミコロンで区切られます。
  • 各要素を個別の行に配置します。この場合、セミコロンセパレータはオプションです。 *シーケンス式を使用する。

ドット演算子(。)と角かっこ([および])を使用して、配列要素にアクセスできます。

次の例は、配列の作成を示しています-

//using semicolon separator
let array1 = [| 1; 2; 3; 4; 5; 6 |]
for i in 0 .. array1.Length - 1 do
   printf "%d " array1.[i]
printfn" "

//without semicolon separator
let array2 =
   [|
      1
      2
      3
      4
      5
   |]
for i in 0 .. array2.Length - 1 do
   printf "%d " array2.[i]
printfn" "

//using sequence
let array3 = [| for i in 1 .. 10 -> i* i |]
for i in 0 .. array3.Length - 1 do
   printf "%d " array3.[i]
printfn" "

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

1 2 3 4 5 6
1 2 3 4 5
1 4 9 16 25 36 49 64 81 100

配列の基本操作

ライブラリモジュールMicrosoft.FSharp.Collections.Arrayは、1次元配列の操作をサポートしています。

次の表は、配列の基本的な操作を示しています-

Value Description
append : 'T [] → 'T [] → 'T [] Creates an array that contains the elements of one array followed by the elements of another array.
average : ^T [] → ^T Returns the average of the elements in an array.
averageBy : ('T → ^U) → 'T [] → ^U Returns the average of the elements generated by applying a function to each element of an array.
blit : 'T [] → int → 'T [] → int → int → unit Reads a range of elements from one array and writes them into another.
choose : ('T → U option) → 'T [] → 'U [] Applies a supplied function to each element of an array. Returns an array that contains the results x for each element for which the function returns Some(x).
collect : ('T → 'U []) → T [] → 'U [] Applies the supplied function to each element of an array, concatenates the results, and returns the combined array.
concat : seq<'T []> → 'T [] Creates an array that contains the elements of each of the supplied sequence of arrays.
copy : 'T → 'T [] Creates an array that contains the elements of the supplied array.
create : int → 'T → 'T [] Creates an array whose elements are all initially the supplied value.
empty : 'T [] Returns an empty array of the given type.
exists : ('T → bool) → 'T [] → bool Tests whether any element of an array satisfies the supplied predicate.
exists2 : ('T1 → 'T2 → bool) → 'T1 [] → 'T2 [] → bool Tests whether any pair of corresponding elements of two arrays satisfy the supplied condition.
fill : 'T [] → int → int → 'T → unit Fills a range of elements of an array with the supplied value.
filter : ('T → bool) → 'T [] → 'T [] Returns a collection that contains only the elements of the supplied array for which the supplied condition returns true.
find : ('T → bool) → 'T [] → 'T Returns the first element for which the supplied function returns true. Raises KeyNotFoundException if no such element exists.
findIndex : ('T → bool) → 'T [] → int Returns the index of the first element in an array that satisfies the supplied condition. Raises KeyNotFoundException if none of the elements satisfy the condition.
fold : ('State → 'T → 'State) → 'State → 'T [] → 'State Applies a function to each element of an array, threading an accumulator argument through the computation. If the input function is f and the array elements are i0…​iN, this function computes f (…​(f s i0)…​) iN.
fold2 : ('State → 'T1 → 'T2 → 'State) → 'State → 'T1 [] → 'T2 [] → 'State Applies a function to pairs of elements from two supplied arrays, left-to-right, threading an accumulator argument through the computation. The two input arrays must have the same lengths; otherwise, ArgumentException is raised.
foldBack : ('T → 'State → 'State) → 'T [] → 'State → 'State Applies a function to each element of an array, threading an accumulator argument through the computation. If the input function is f and the array elements are i0…​iN, this function computes f i0 (…​(f iN s)).
foldBack2 : ('T1 → 'T2 → 'State → 'State) → 'T1 [] → 'T2 [] → 'State → 'State Applies a function to pairs of elements from two supplied arrays, right-to-left, threading an accumulator argument through the computation. The two input arrays must have the same lengths; otherwise, ArgumentException is raised.
forall : ('T → bool) → 'T [] → bool Tests whether all elements of an array satisfy the supplied condition.
forall2 : ('T1 → 'T2 → bool) → 'T1 [] → 'T2 [] → bool Tests whether all corresponding elements of two supplied arrays satisfy a supplied condition.
get : 'T [] → int → 'T Gets an element from an array.
init : int → (int → 'T) → 'T [] Uses a supplied function to create an array of the supplied dimension.
isEmpty : 'T [] → bool Tests whether an array has any elements.
iter : ('T → unit) → 'T [] → unit Applies the supplied function to each element of an array.
iter2 : ('T1 → 'T2 → unit) → 'T1 [] → 'T2 [] → unit) Applies the supplied function to a pair of elements from matching indexes in two arrays. The two arrays must have the same lengths; otherwise, ArgumentException is raised.
iteri : (int → 'T → unit) → 'T [] → unit Applies the supplied function to each element of an array. The integer passed to the function indicates the index of the element.
iteri2 : (int → 'T1 → 'T2 → unit) → 'T1 [] → 'T2 [] → unit Applies the supplied function to a pair of elements from matching indexes in two arrays, also passing the index of the elements. The two arrays must have the same lengths; otherwise, an ArgumentException is raised.
length : 'T [] → int Returns the length of an array. The Length property does the same thing.
map : ('T → 'U) → 'T [] → 'U [] Creates an array whose elements are the results of applying the supplied function to each of the elements of a supplied array.
map2 : ('T1 → 'T2 → 'U) → 'T1 [] → 'T2 [] → 'U [] Creates an array whose elements are the results of applying the supplied function to the corresponding elements of two supplied arrays. The two input arrays must have the same lengths; otherwise, ArgumentException is raised.
mapi : (int → 'T → 'U) → 'T [] → 'U [] Creates an array whose elements are the results of applying the supplied function to each of the elements of a supplied array. An integer index passed to the function indicates the index of the element being transformed.
mapi2 : (int → 'T1 → 'T2 → 'U) → 'T1 [] → 'T2 [] → 'U [] Creates an array whose elements are the results of applying the supplied function to the corresponding elements of the two collections pairwise, also passing the index of the elements. The two input arrays must have the same lengths; otherwise, ArgumentException is raised.
max : 'T [] → 'T Returns the largest of all elements of an array. Operators.max is used to compare the elements.
maxBy : ('T → 'U) → 'T [] → 'T Returns the largest of all elements of an array, compared via Operators.max on the function result.
min : ('T [] → 'T Returns the smallest of all elements of an array. Operators.min is used to compare the elements.
minBy : ('T → 'U) → 'T [] → 'T Returns the smallest of all elements of an array. Operators.min is used to compare the elements.
ofList : 'T list → 'T [] Creates an array from the supplied list.
ofSeq : seq<'T> → 'T [] Creates an array from the supplied enumerable object.
partition : ('T → bool) → 'T [] → 'T [] *'T [] Splits an array into two arrays, one containing the elements for which the supplied condition returns* true, and the other containing those for which it returns false*.
permute : (int → int) → 'T [] → 'T [] Permutes the elements of an array according to the specified permutation.
pick : ('T → 'U option) → 'T [] → 'U Applies the supplied function to successive elements of a supplied array, returning the first result where the function returns Some(x) for some x. If the function never returns Some(x), KeyNotFoundException is raised.
reduce : ('T → 'T → 'T) → 'T [] → 'T Applies a function to each element of an array, threading an accumulator argument through the computation. If the input function is f and the array elements are i0…​iN, this function computes f (…​(f i0 i1)…​) iN. If the array has size zero, ArgumentException is raised.
reduceBack : ('T → 'T → 'T) → 'T [] → 'T Applies a function to each element of an array, threading an accumulator argument through the computation. If the input function is f and the elements are i0…​iN, this function computes f i0 (…​(f iN-1 iN)). If the array has size zero, ArgumentException is raised.
rev : 'T [] → 'T [] Reverses the order of the elements in a supplied array.
scan : ('State → 'T → 'State) → 'State → 'T [] → 'State []) Behaves like fold, but returns the intermediate results together with the final results.
scanBack : ('T → 'State → 'State) → 'T [] → 'State → 'State [] Behaves like foldBack, but returns the intermediary results together with the final results.
set : 'T [] → int → 'T → unit Sets an element of an array.
sort : 'T[] → 'T [] Sorts the elements of an array and returns a new array. Operators.compare is used to compare the elements.
sortBy : ('T → 'Key) → 'T [] → 'T [] Sorts the elements of an array by using the supplied function to transform the elements to the type on which the sort operation is based, and returns a new array. Operators.compare is used to compare the elements.
sortInPlace : 'T [] → unit Sorts the elements of an array by changing the array in place, using the supplied comparison function. Operators.compare is used to compare the elements.
sortInPlaceBy : ('T → 'Key) → 'T [] → unit Sorts the elements of an array by changing the array in place, using the supplied projection for the keys. Operators.compare is used to compare the elements.
sortInPlaceWith : ('T → 'T → int) → 'T [] → unit Sorts the elements of an array by using the supplied comparison function to change the array in place.
sortWith : ('T → 'T → int) → 'T [] → 'T [] Sorts the elements of an array by using the supplied comparison function, and returns a new array.
sub : 'T [] → int → int → 'T [] Creates an array that contains the supplied subrange, which is specified by starting index and length.
sum : 'T [] → ^T Returns the sum of the elements in the array.
sumBy : ('T → ^U) → 'T [] → ^U Returns the sum of the results generated by applying a function to each element of an array.
toList : 'T [] → 'T list Converts the supplied array to a list.
toSeq : 'T [] → seq<'T> Views the supplied array as a sequence.
tryFind : ('T → bool) → 'T [] → 'T option Returns the first element in the supplied array for which the supplied function returns true. Returns *None *if no such element exists.
tryFindIndex : ('T → bool) → 'T [] → int option Returns the index of the first element in an array that satisfies the supplied condition.
tryPick : ('T → 'U option) → 'T [] → 'U option Applies the supplied function to successive elements of the supplied array, and returns the first result where the function returns Some(x) for some x. If the function never returns Some(x),* None *is returned.
unzip : ('T1* 'T2) [] → 'T1 [] *'T2 [] Splits an array of tuple pairs into a tuple of two arrays.
unzip3 : ('T1* 'T2 'T3) [] → 'T1 [] 'T2 [] *'T3 [] Splits an array of tuples of three elements into a tuple of three arrays.
zeroCreate : int → 'T [] Creates an array whose elements are initially set to the default value Unchecked.defaultof<'T>.
zip : 'T1 [] → 'T2 [] → ('T1* 'T2) [] Combines two arrays into an array of tuples that have two elements. The two arrays must have equal lengths; otherwise, ArgumentException is raised.
zip3 : 'T1 [] → 'T2 [] → 'T3 [] → ('T1 'T2 113 'T3) [] Combines three arrays into an array of tuples that have three elements. The three arrays must have equal lengths; otherwise, ArgumentException is raised.

次のセクションでは、これらの機能の一部の使用方法について説明します。

関数を使用して配列を作成する

Arrayモジュールには、配列を最初から作成するいくつかの関数があります。

  • Array.empty 関数は、新しい空の配列を作成します。
  • Array.create 関数は、指定されたサイズの配列を作成し、すべての要素を指定された値に設定します。
  • Array.init 関数は、要素を生成する次元と関数を指定して、配列を作成します。
  • Array.zeroCreate 関数は、すべての要素がゼロ値に初期化される配列を作成します。
  • Array.copy 関数は、既存の配列からコピーされた要素を含む新しい配列を作成します。
  • Array.sub 関数は、配列の部分範囲から新しい配列を生成します。
  • Array.append 関数は、2つの既存の配列を組み合わせて新しい配列を作成します。
  • Array.choose 関数は、新しい配列に含める配列の要素を選択します。
  • Array.collect 関数は、既存の配列の各配列要素に対して指定された関数を実行し、関数によって生成された要素を収集して、それらを新しい配列に結合します。
  • Array.concat 関数は配列のシーケンスを取り、それらを単一の配列に結合します。
  • Array.filter 関数はブール条件関数を取り、条件が真である入力配列からの要素のみを含む新しい配列を生成します。
  • Array.rev 関数は、既存の配列の順序を逆にして新しい配列を生成します。

次の例は、これらの機能を示しています-

例1

( *using create and set* )
let array1 = Array.create 10 ""
for i in 0 .. array1.Length - 1 do
   Array.set array1 i (i.ToString())
for i in 0 .. array1.Length - 1 do
   printf "%s " (Array.get array1 i)
printfn " "

( *empty array* )
let array2 = Array.empty
printfn "Length of empty array: %d" array2.Length

let array3 = Array.create 10 7.0
printfn "Float Array: %A" array3

( *using the init and zeroCreate* )
let array4 = Array.init 10 (fun index -> index * index)
printfn "Array of squares: %A" array4

let array5 : float array = Array.zeroCreate 10
let (myZeroArray : float array) = Array.zeroCreate 10
printfn "Float Array: %A" array5

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

0 1 2 3 4 5 6 7 8 9
Length of empty array: 0
Float Array: [|7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0|]
Array of squares: [|0; 1; 4; 9; 16; 25; 36; 49; 64; 81|]
Float Array: [|0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0|]

例2

( *creating subarray from element 5* )
( *containing 15 elements thereon* )

let array1 = [| 0 .. 50 |]
let array2 = Array.sub array1 5 15
printfn "Sub Array:"
printfn "%A" array2

( *appending two arrays* )
let array3 = [| 1; 2; 3; 4|]
let array4 = [| 5 .. 9 |]
printfn "Appended Array:"
let array5 = Array.append array3 array4
printfn "%A" array5

( *using the Choose function* )
let array6 = [| 1 .. 20 |]
let array7 = Array.choose (fun elem -> if elem % 3 = 0 then
   Some(float (elem))
      else
   None) array6

printfn "Array with Chosen elements:"
printfn "%A" array7

(*using the Collect function *)
let array8 = [| 2 .. 5 |]
let array9 = Array.collect (fun elem -> [| 0 .. elem - 1 |]) array8
printfn "Array with collected elements:"
printfn "%A" array9

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Sub Array:
[|5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19|]
Appended Array:
[|1; 2; 3; 4; 5; 6; 7; 8; 9|]
Array with Chosen elements:
[|3.0; 6.0; 9.0; 12.0; 15.0; 18.0|]
Array with collected elements:
[|0; 1; 0; 1; 2; 0; 1; 2; 3; 0; 1; 2; 3; 4|]

配列の検索

*Array.find* 関数はブール関数を取り、関数がtrueを返す最初の要素を返します。それ以外の場合はKeyNotFoundExceptionを発生させます。
*Array.findIndex* 関数は、要素自体ではなく要素のインデックスを返すことを除いて、同様に機能します。

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

マイクロソフトは、この興味深いプログラム例を提供します。これは、完全な正方形と完全な立方体の両方である、与えられた数の範囲の最初の要素を見つけます-

let array1 = [| 2 .. 100 |]
let delta = 1.0e-10
let isPerfectSquare (x:int) =
   let y = sqrt (float x)
   abs(y - round y) < delta

let isPerfectCube (x:int) =
   let y = System.Math.Pow(float x, 1.0/3.0)
   abs(y - round y) < delta

let element = Array.find (fun elem -> isPerfectSquare elem && isPerfectCube elem) array1

let index = Array.findIndex (fun elem -> isPerfectSquare elem && isPerfectCube elem) array1

printfn "The first element that is both a square and a cube is %d and its index is %d." element index

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

The first element that is both a square and a cube is 64 and its index is 62.

F#-可変リスト

*List <'T>* クラスは、インデックスによってアクセスできるオブジェクトの厳密に型指定されたリストを表します。

これは、Listクラスの可変の対応物です。 インデックスからアクセスできるため、配列と似ていますが、配列とは異なり、リストのサイズを変更できます。 したがって、宣言時にサイズを指定する必要はありません。

可変リストの作成

リストは new キーワードを使用して作成され、リストのコンストラクターを呼び出します。 次の例はこれを示しています-

( *Creating a List* )
open System.Collections.Generic

let booksList = new List<string>()
booksList.Add("Gone with the Wind")
booksList.Add("Atlas Shrugged")
booksList.Add("Fountainhead")
booksList.Add("Thornbirds")
booksList.Add("Rebecca")
booksList.Add("Narnia")

booksList |> Seq.iteri (fun index item -> printfn "%i: %s" index booksList.[index])

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

0: Gone with the Wind
1: Atlas Shrugged
2: Fountainhead
3: Thornbirds
4: Rebecca
5: Narnia

List(T)クラス

List(T)クラスは、インデックスによってアクセスできるオブジェクトの厳密に型指定されたリストを表します。 リストを検索、ソート、および操作するメソッドを提供します。

次の表は、List(T)クラスのプロパティ、コンストラクタ、およびメソッドを提供します-

プロパティ

Property Description
Capacity Gets or sets the total number of elements the internal data structure can hold without resizing.
Count Gets the number of elements contained in the List(T).
Item Gets or sets the element at the specified index.

コンストラクタ

Constructor Description
List(T)() Initializes a new instance of the List(T) class that is empty and has the default initial capacity.
List(T)(IEnumerable(T)) Initializes a new instance of the List(T) class that contains elements copied from the specified collection and has sufficient capacity to accommodate the number of elements copied.
List(T)(Int32) Initializes a new instance of the List(T) class that is empty and has the specified initial capacity.

方法

Methods Description
Add Adds an object to the end of the List(T).
AddRange Adds the elements of the specified collection to the end of the List(T).
AsReadOnly Returns a read-only IList(T) wrapper for the current collection.
BinarySearch(T) Searches the entire sorted List(T) for an element using the default comparer and returns the zero-based index of the element.
BinarySearch(T, IComparer(T)) Searches the entire sorted List(T) for an element using the specified comparer and returns the zero-based index of the element.
BinarySearch(Int32, Int32, T, IComparer(T)) Searches a range of elements in the sorted List(T) for an element using the specified comparer and returns the zero-based index of the element.
Clear Removes all elements from the List(T).
Contains Determines whether an element is in the List(T).
ConvertAll(TOutput) Converts the elements in the current List(T) to another type, and returns a list containing the converted elements.
CopyTo(T[]) Copies the entire List(T) to a compatible one-dimensional array, starting at the beginning of the target array.
CopyTo(T[], Int32) Copies the entire List(T) to a compatible one-dimensional array, starting at the specified index of the target array.
CopyTo(Int32, T[], Int32, Int32) Copies a range of elements from the List(T) to a compatible one-dimensional array, starting at the specified index of the target array.
Equals(Object) Determines whether the specified object is equal to the current object. (Inherited from Object.)
Exists Determines whether the List(T) contains elements that match the conditions defined by the specified predicate.
Finalize Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection (Inherited from Object).
Find Searches for an element that matches the conditions defined by the specified predicate, and returns the first occurrence within the entire List(T).
FindAll Retrieves all the elements that match the conditions defined by the specified predicate.
FindIndex(Predicate(T)) Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the first occurrence within the entire List(T).
FindIndex(Int32, Predicate(T)) Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the first occurrence within the range of elements in the List(T) that extends from the specified index to the last element.
FindIndex(Int32, Int32, Predicate(T)) Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the first occurrence within the range of elements in the List(T) that starts at the specified index and contains the specified number of elements.
FindLast Searches for an element that matches the conditions defined by the specified predicate, and returns the last occurrence within the entire List(T).
FindLastIndex(Predicate(T)) Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the last occurrence within the entire List(T).
FindLastIndex(Int32, Predicate(T)) Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the last occurrence within the range of elements in the List(T) that extends from the first element to the specified index.
FindLastIndex(Int32, Int32, Predicate(T)) Searches for an element that matches the conditions defined by the specified predicate, and returns the zero-based index of the last occurrence within the range of elements in the List(T) that contains the specified number of elements and ends at the specified index.
ForEach Performs the specified action on each element of the List(T).
GetEnumerator Returns an enumerator that iterates through the List(T).
GetHashCode Serves as the default hash function. (Inherited from Object.)
GetRange Creates a shallow copy of a range of elements in the source List(T).
GetType Gets the Type of the current instance. (Inherited from Object.)
IndexOf(T) Searches for the specified object and returns the zero-based index of the first occurrence within the entire List(T).
IndexOf(T, Int32) Searches for the specified object and returns the zero-based index of the first occurrence within the range of elements in the List(T) that extends from the specified index to the last element.
IndexOf(T, Int32, Int32) Searches for the specified object and returns the zero-based index of the first occurrence within the range of elements in the List(T) that starts at the specified index and contains the specified number of elements.
Insert Inserts an element into the List(T) at the specified index.
InsertRange Inserts the elements of a collection into the List(T) at the specified index.
LastIndexOf(T) Searches for the specified object and returns the zero-based index of the last occurrence within the entire List(T).
LastIndexOf(T, Int32) Searches for the specified object and returns the zero-based index of the last occurrence within the range of elements in the List(T) that extends from the first element to the specified index.
LastIndexOf(T, Int32, Int32) Searches for the specified object and returns the zero-based index of the last occurrence within the range of elements in the List(T) that contains the specified number of elements and ends at the specified index.
MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)
Remove Removes the first occurrence of a specific object from the List(T).
RemoveAll Removes all the elements that match the conditions defined by the specified predicate.
RemoveAt Removes the element at the specified index of the List(T).
RemoveRange Removes a range of elements from the List(T).
Reverse() Reverses the order of the elements in the entire List(T).
Reverse(Int32, Int32) Reverses the order of the elements in the specified range.
Sort() Sorts the elements in the entire List(T) using the default comparer.
Sort(Comparison(T)) Sorts the elements in the entire List(T) using the specified System. Comparison(T).
Sort(IComparer(T)) Sorts the elements in the entire List(T) using the specified comparer.
Sort(Int32, Int32, IComparer(T)) Sorts the elements in a range of elements in List(T) using the specified comparer.
ToArray Copies the elements of the List(T) to a new array.
ToString Returns a string that represents the current object. (Inherited from Object.)
TrimExcess Sets the capacity to the actual number of elements in the List(T), if that number is less than a threshold value.
TrueForAll Determines whether every element in the List(T) matches the conditions defined by the specified predicate.

( *Creating a List* )
open System.Collections.Generic

let booksList = new List<string>()
booksList.Add("Gone with the Wind")
booksList.Add("Atlas Shrugged")
booksList.Add("Fountainhead")
booksList.Add("Thornbirds")
booksList.Add("Rebecca")
booksList.Add("Narnia")

printfn"Total %d books" booksList.Count
booksList |> Seq.iteri (fun index item -> printfn "%i: %s" index booksList.[index])
booksList.Insert(2, "Roots")

printfn("after inserting at index 2")
printfn"Total %d books" booksList.Count

booksList |> Seq.iteri (fun index item -> printfn "%i: %s" index booksList.[index])
booksList.RemoveAt(3)

printfn("after removing from index 3")
printfn"Total %d books" booksList.Count

booksList |> Seq.iteri (fun index item -> printfn "%i: %s" index booksList.[index])

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Total 6 books
0: Gone with the Wind
1: Atlas Shrugged
2: Fountainhead
3: Thornbirds
4: Rebecca
5: Narnia
after inserting at index 2
Total 7 books
0: Gone with the Wind
1: Atlas Shrugged
2: Roots
3: Fountainhead
4: Thornbirds
5: Rebecca
6: Narnia
after removing from index 3
Total 6 books
0: Gone with the Wind
1: Atlas Shrugged
2: Roots
3: Thornbirds
4: Rebecca
5: Narnia

F#-可変辞書

*Dictionary <'TKey、' TValue>* クラスは、F#マップデータ構造の可変アナログであり、同じ機能の多くが含まれています。

F#のマップの章から復習すると、マップは値をキーに関連付ける特別な種類のセットです。

可変辞書の作成

可変辞書は、 new キーワードを使用してリストのコンストラクターを呼び出して作成されます。 次の例はこれを示しています-

open System.Collections.Generic
let dict = new Dictionary<string, string>()
dict.Add("1501", "Zara Ali")
dict.Add("1502","Rishita Gupta")
dict.Add("1503","Robin Sahoo")
dict.Add("1504","Gillian Megan")
printfn "Dictionary - students: %A" dict

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Dictionary - students: seq
[[Zara Ali]; [1502, Rishita Gupta]; [1503, Robin Sahoo];
[1504, Gillian Megan]]

Dictionary(TKey、TValue)クラス

Dictionary(TKey、TValue)クラスは、キーと値のコレクションを表します。

次の表は、List(T)クラスのプロパティ、コンストラクタ、およびメソッドを提供します-

プロパティ

Property Description
Comparer Gets the IEqualityComparer(T) that is used to determine equality of keys for the dictionary.
Count Gets the number of key/value pairs contained in the Dictionary(TKey, TValue).
Item Gets or sets the value associated with the specified key.
Keys Gets a collection containing the keys in the Dictionary(TKey, TValue).
Values Gets a collection containing the values in the Dictionary(TKey, TValue).

コンストラクタ

Constructors Description
Dictionary(TKey, TValue)() Initializes a new instance of the *Dictionary(TKey, TValue) *class that is empty, has the default initial capacity, and uses the default equality comparer for the key type.
Dictionary(TKey, TValue)(IDictionary(TKey, TValue)) Initializes a new instance of the* Dictionary(TKey, TValue) class that contains elements copied from the specified IDictionary(TKey, TValue) *and uses the default equality comparer for the key type.
Dictionary(TKey, TValue)(IEqualityComparer(TKey)) Initializes a new instance of the* Dictionary(TKey, TValue) class that is empty, has the default initial capacity, and uses the specified IEqualityComparer(T). *
Dictionary(TKey, TValue)(Int32) Initializes a new instance of the* Dictionary(TKey, TValue) *class that is empty, has the specified initial capacity, and uses the default equality comparer for the key type.
Dictionary(TKey, TValue)(IDictionary(TKey, TValue), IEqualityComparer(TKey)) Initializes a new instance of the* Dictionary(TKey, TValue) class that contains elements copied from the specified IDictionary(TKey, TValue) and uses the specified IEqualityComparer(T). *
Dictionary(TKey, TValue)(Int32, IEqualityComparer(TKey)) Initializes a new instance of the* Dictionary(TKey, TValue) class that is empty, has the specified initial capacity, and uses the specified IEqualityComparer(T). *
Dictionary(TKey, TValue)(SerializationInfo, StreamingContext) Initializes a new instance of the* ictionary(TKey, TValue)* class with serialized data.

方法

Method Description
Add Adds the specified key and value to the dictionary.
Clear Removes all keys and values from the Dictionary(TKey, TValue).
ContainsKey Determines whether the Dictionary(TKey, TValue) contains the specified key.
ContainsValue Determines whether the Dictionary(TKey, TValue) contains a specific value.
Equals(Object) Determines whether the specified object is equal to the current object. (Inherited from Object.)
Finalize Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection. (Inherited from Object.)
GetEnumerator Returns an enumerator that iterates through the Dictionary(TKey, TValue).
GetHashCode Serves as the default hash function. (Inherited from Object.)
GetObjectData Implements the System.Runtime.Serialization.ISerializable interface and returns the data needed to serialize the Dictionary(TKey, TValue)instance.
GetType Gets the Type of the current instance. (Inherited from Object.)
MemberwiseClone Creates a shallow copy of the current Object. (Inherited from Object.)
OnDeserialization Implements the System.Runtime.Serialization.ISerializable interface and raises the deserialization event when the deserialization is complete.
Remove Removes the value with the specified key from the Dictionary(TKey, TValue).
ToString Returns a string that represents the current object. (Inherited from Object.)
TryGetValue Gets the value associated with the specified key.

open System.Collections.Generic
let dict = new Dictionary<string, string>()

dict.Add("1501", "Zara Ali")
dict.Add("1502","Rishita Gupta")
dict.Add("1503","Robin Sahoo")
dict.Add("1504","Gillian Megan")

printfn "Dictionary - students: %A" dict
printfn "Total Number of Students: %d" dict.Count
printfn "The keys: %A" dict.Keys
printf"The Values: %A" dict.Values

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Dictionary - students: seq
[[Zara Ali]; [1502, Rishita Gupta]; [1503, Robin Sahoo];
[1504, Gillian Megan]]
Total Number of Students: 4
The keys: seq ["1501"; "1502"; "1503"; "1504"]
The Values: seq ["Zara Ali"; "Rishita Gupta"; "Robin Sahoo"; "Gillian Megan"]

F#-基本的なI/O

基本入出力には以下が含まれます-

  • コンソールからの読み取りとコンソールへの書き込み。
  • ファイルの読み取りと書き込み。

Core.Printfモジュール

コンソールへの書き込みには、_printf_および_printfn_関数を使用しました。 このセクションでは、F#の Printf モジュールの詳細を調べます。

上記の関数とは別に、F#の_Core.Printf_モジュールには、%マーカーをプレースホルダーとして使用して印刷および書式設定するためのさまざまなメソッドがあります。 次の表は、簡単な説明とメソッドを示しています-

Value Description
bprintf : StringBuilder → BuilderFormat<'T> → 'T Prints to a StringBuilder.
eprintf : TextWriterFormat<'T> → 'T Prints formatted output to stderr.
eprintfn : TextWriterFormat<'T> → 'T Prints formatted output to stderr, adding a newline.
failwithf : StringFormat<'T,'Result> → 'T Prints to a string buffer and raises an exception with the given result.
fprintf : TextWriter → TextWriterFormat<'T> → 'T Prints to a text writer.
fprintfn : TextWriter → TextWriterFormat<'T> → 'T Prints to a text writer, adding a newline.
kbprintf : (unit → 'Result) → StringBuilder → BuilderFormat<'T,'Result> → 'T Like bprintf, but calls the specified function to generate the result.
kfprintf : (unit → 'Result) → TextWriter → TextWriterFormat<'T,'Result> → 'T Like fprintf, but calls the specified function to generate the result.
kprintf : (string → 'Result) → StringFormat<'T,'Result> → 'T Like printf, but calls the specified function to generate the result. For example, these let the printing force a flush after all output has been entered onto the channel, but not before.
ksprintf : (string → 'Result) → StringFormat<'T,'Result> → 'T Like sprintf, but calls the specified function to generate the result.
printf : TextWriterFormat<'T> → 'T Prints formatted output to stdout.
printfn : TextWriterFormat<'T> → 'T Prints formatted output to stdout, adding a newline.
sprintf : StringFormat<'T> → 'T Prints to a string by using an internal string buffer and returns the result as a string.

フォーマット仕様

フォーマット仕様は、プログラマーのニーズに応じて、入力または出力のフォーマットに使用されます。

これらは、フォーマットプレースホルダーを示す%マーカー付きの文字列です。

Formatプレースホルダーの構文は次のとおりです-

%[flags][width][.precision][type]
*type* は次のように解釈されます-
Type Description
%b Formats a bool, *formatted as true or false*.
%c Formats a character.
%s Formats a *string, *formatted as its contents, without interpreting any escape characters.
%d, %i Formats any basic integer type formatted as a decimal integer, signed if the basic integer type is signed.
%u Formats any basic integer type formatted as an unsigned decimal integer.
%x Formats any basic integer type formatted as an unsigned hexadecimal integer, using lowercase letters a through f.
%X Formats any basic integer type formatted as an unsigned hexadecimal integer, using uppercase letters A through F.
%o Formats any basic integer type formatted as an unsigned octal integer.
%e, %E, %f, %F, %g, %G Formats any basic floating point type* (float, float32) *formatted using a C-style floating point format specifications.
%e, %E Formats a signed value having the form [-]d.dddde[sign]ddd where d is a single decimal digit, dddd is one or more decimal digits, ddd is exactly three decimal digits, and sign is + or -.
%f Formats a signed value having the form [-]dddd.dddd, where dddd is one or more decimal digits. The number of digits before the decimal point depends on the magnitude of the number, and the number of digits after the decimal point depends on the requested precision.
%g, %G Formats a signed value printed in f or e format, whichever is more compact for the given value and precision.
%M Formats a Decimal value.
%O Formats any value, printed by boxing the object and using its* ToString *method.
%A, %+A Formats any value, printed with the default layout settings. Use %+A to print the structure of discriminated unions with internal and private representations.
%a

A general format specifier, requires two arguments. The first argument is a function which accepts two arguments: first, a context parameter of the appropriate type for the given formatting function (for example, a TextWriter), and second, a value to print and which either outputs or returns appropriate text.

2番目の引数は、印刷する特定の値です。

%t A general format specifier, requires one argument: a function which accepts a context parameter of the appropriate type for the given formatting function (aTextWriter) and which either outputs or returns appropriate text. Basic integer types are* byte, sbyte, int16, uint16, int32, uint32, int64, uint64, nativeint, and unativeint. Basic floating point types are float and float32.*
*width* はオプションのパラメーターです。 結果の最小幅を示す整数です。 たとえば、%5dは、少なくとも5文字のスペースを含む整数を出力します。

有効な*フラグ*は次の表に記載されています-

Value Description
0 Specifies to add zeros instead of spaces to make up the required width.
- Specifies to left-justify the result within the width specified.
+ Specifies to add a + character if the number is positive (to match a - sign for negative numbers).
' ' (space) Specifies to add an extra space if the number is positive (to match a - sign for negative numbers).
# Invalid.

printf "Hello "
printf "World"
printfn ""
printfn "Hello "
printfn "World"
printf "Hi, I'm %s and I'm a %s" "Rohit" "Medical Student"

printfn "d: %f" 212.098f
printfn "e: %f" 504.768f

printfn "x: %g" 212.098f
printfn "y: %g" 504.768f

printfn "x: %e" 212.098f
printfn "y: %e" 504.768f
printfn "True: %b" true

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Hello World
Hello
World
Hi, I'm Rohit and I'm a Medical Studentd: 212.098000
e: 504.768000
x: 212.098
y: 504.768
x: 2.120980e+002
y: 5.047680e+002
True: true

コンソールクラス

このクラスは、.NETフレームワークの一部です。 コンソールアプリケーションの標準入力、出力、およびエラーストリームを表します。

コンソールから読み取り、コンソールに書き込むためのさまざまな方法を提供します。 次の表は、メソッドを示しています-

Method Description
Beep() Plays the sound of a beep through the console speaker.
Beep(Int32, Int32) Plays the sound of a beep of a specified frequency and duration through the console speaker.
Clear Clears the console buffer and corresponding console window of display information.
MoveBufferArea(Int32, Int32, Int32, Int32, Int32, Int32) Copies a specified source area of the screen buffer to a specified destination area.
MoveBufferArea(Int32, Int32, Int32, Int32, Int32, Int32, Char, ConsoleColor, ConsoleColor) Copies a specified source area of the screen buffer to a specified destination area.
OpenStandardError() Acquires the standard error stream.
OpenStandardError(Int32) Acquires the standard error stream, which is set to a specified buffer size.
OpenStandardInput() Acquires the standard input stream.
OpenStandardInput(Int32) Acquires the standard input stream, which is set to a specified buffer size.
OpenStandardOutput() Acquires the standard output stream.
OpenStandardOutput(Int32) Acquires the standard output stream, which is set to a specified buffer size.
Read Reads the next character from the standard input stream.
ReadKey() Obtains the next character or function key pressed by the user. The pressed key is displayed in the console window.
ReadKey(Boolean) Obtains the next character or function key pressed by the user. The pressed key is optionally displayed in the console window.
ReadLine Reads the next line of characters from the standard input stream.
ResetColor Sets the foreground and background console colors to their defaults.
SetBufferSize Sets the height and width of the screen buffer area to the specified values.
SetCursorPosition Sets the position of the cursor.
SetError Sets the Error property to the specified TextWriter object.
SetIn Sets the In property to the specified TextReader object.
SetOut Sets the Out property to the specified TextWriter object.
SetWindowPosition Sets the position of the console window relative to the screen buffer.
SetWindowSize Sets the height and width of the console window to the specified values.
Write(Boolean) Writes the text representation of the specified Boolean value to the standard output stream.
Write(Char) Writes the specified Unicode character value to the standard output stream.
Write(Char[]) Writes the specified array of Unicode characters to the standard output stream.
Write(Decimal) Writes the text representation of the specified Decimal value to the standard output stream.
Write(Double) Writes the text representation of the specified double-precision floating-point value to the standard output stream.
Write(Int32) Writes the text representation of the specified 32-bit signed integer value to the standard output stream.
Write(Int64) Writes the text representation of the specified 64-bit signed integer value to the standard output stream.
Write(Object) Writes the text representation of the specified object to the standard output stream.
Write(Single) Writes the text representation of the specified single-precision floating-point value to the standard output stream.
Write(String) Writes the specified string value to the standard output stream.
Write(UInt32) Writes the text representation of the specified 32-bit unsigned integer value to the standard output stream.
Write(UInt64) Writes the text representation of the specified 64-bit unsigned integer value to the standard output stream.
Write(String, Object) Writes the text representation of the specified object to the standard output stream using the specified format information.
Write(String, Object[]) Writes the text representation of the specified array of objects to the standard output stream using the specified format information.
Write(Char[], Int32, Int32) Writes the specified subarray of Unicode characters to the standard output stream.
Write(String, Object, Object) Writes the text representation of the specified objects to the standard output stream using the specified format information.
Write(String, Object, Object, Object) Writes the text representation of the specified objects to the standard output stream using the specified format information.
Write(String, Object, Object, Object, Object) Writes the text representation of the specified objects and variable-length parameter list to the standard output stream using the specified format information.
WriteLine() Writes the current line terminator to the standard output stream.
WriteLine(Boolean) Writes the text representation of the specified Boolean value, followed by the current line terminator, to the standard output stream.
WriteLine(Char) Writes the specified Unicode character, followed by the current line terminator, value to the standard output stream.
WriteLine(Char[]) Writes the specified array of Unicode characters, followed by the current line terminator, to the standard output stream.
WriteLine(Decimal) Writes the text representation of the specified Decimal value, followed by the current line terminator, to the standard output stream.
WriteLine(Double) Writes the text representation of the specified double-precision floating-point value, followed by the current line terminator, to the standard output stream.
WriteLine(Int32) Writes the text representation of the specified 32-bit signed integer value, followed by the current line terminator, to the standard output stream.
WriteLine(Int64) Writes the text representation of the specified 64-bit signed integer value, followed by the current line terminator, to the standard output stream.
WriteLine(Object) Writes the text representation of the specified object, followed by the current line terminator, to the standard output stream.
WriteLine(Single) Writes the text representation of the specified single-precision floating-point value, followed by the current line terminator, to the standard output stream.
WriteLine(String) Writes the specified string value, followed by the current line terminator, to the standard output stream.
WriteLine(UInt32) Writes the text representation of the specified 32-bit unsigned integer value, followed by the current line terminator, to the standard output stream.
WriteLine(UInt64) Writes the text representation of the specified 64-bit unsigned integer value, followed by the current line terminator, to the standard output stream.
WriteLine(String, Object) Writes the text representation of the specified object, followed by the current line terminator, to the standard output stream using the specified format information.
WriteLine(String, Object[]) Writes the text representation of the specified array of objects, followed by the current line terminator, to the standard output stream using the specified format information.
WriteLine(Char[], Int32, Int32) Writes the specified subarray of Unicode characters, followed by the current line terminator, to the standard output stream.
WriteLine(String, Object, Object) Writes the text representation of the specified objects, followed by the current line terminator, to the standard output stream using the specified format information.
WriteLine(String, Object, Object, Object) Writes the text representation of the specified objects, followed by the current line terminator, to the standard output stream using the specified format information.
WriteLine(String, Object, Object, Object, Object) Writes the text representation of the specified objects and variable-length parameter list, followed by the current line terminator, to the standard output stream using the specified format information.

次の例は、コンソールからの読み取りとコンソールへの書き込みを示しています-

open System
let main() =
   Console.Write("What's your name? ")
   let name = Console.ReadLine()
   Console.Write("Hello, {0}\n", name)
   Console.WriteLine(System.String.Format("Big Greetings from {0} and {1}", "finddevguides", "Absoulte Classes"))
   Console.WriteLine(System.String.Format("|{0:yyyy-MMM-dd}|", System.DateTime.Now))
main()

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

What's your name? Kabir
Hello, Kabir
Big Greetings from finddevguides and Absoulte Classes
|2015-Jan-05|

System.IO名前空間

System.IO名前空間には、基本的なI/Oを実行するためのさまざまな便利なクラスが含まれています。

これには、ファイルとデータストリームの読み取りと書き込みを可能にするタイプまたはクラス、および基本的なファイルとディレクトリのサポートを提供するタイプが含まれています。

ファイルシステムでの作業に役立つクラス-

  • System.IO.Fileクラスは、ファイルの作成、追加、削除に使用されます。
  • System.IO.Directoryクラスは、ディレクトリの作成、移動、および削除に使用されます。
  • System.IO.Pathクラスは、ファイルパスを表す文字列に対して操作を実行します。
  • System.IO.FileSystemWatcherクラスを使用すると、ユーザーはディレクトリの変更をリッスンできます。

ストリームの操作に役立つクラス(バイトのシーケンス)-

  • System.IO.StreamReaderクラスは、ストリームから文字を読み取るために使用されます。
  • System.IO.StreamWriterクラスは、ストリームに文字を書き込むために使用されます。
  • System.IO.MemoryStreamクラスは、メモリ内のバイトストリームを作成します。

次の表は、簡単な説明と名前空間で提供されるすべてのクラスを示しています-

Class Description
BinaryReader Reads primitive data types as binary values in a specific encoding.
BinaryWriter Writes primitive types in binary to a stream and supports writing strings in a specific encoding.
BufferedStream Adds a buffering layer to read and write operations on another stream.
Directory Exposes static methods for creating, moving, and enumerating through directories and subdirectories.
DirectoryInfo Exposes instance methods for creating, moving, and enumerating through directories and subdirectories.
DirectoryNotFoundException The exception that is thrown when part of a file or directory cannot be found.
DriveInfo Provides access to information on a drive.
DriveNotFoundException The exception that is thrown when trying to access a drive or share that is not available.
EndOfStreamException The exception that is thrown when reading is attempted past the end of a stream.
ErrorEventArgs Provides data for the FileSystemWatcher.Error event.
File Provides static methods for the creation, copying, deletion, moving, and opening of a single file, and aids in the creation of FileStream objects.
FileFormatException The exception that is thrown when an input file or a data stream that is supposed to conform to a certain file format specification is malformed.
FileInfo Provides properties and instance methods for the creation, copying, deletion, moving, and opening of files, and aids in the creation of FileStream objects.
FileLoadException The exception that is thrown when a managed assembly is found but cannot be loaded.
FileNotFoundException The exception that is thrown when an attempt to access a file that does not exist on disk fails.
FileStream Exposes a Stream around a file, supporting both synchronous and asynchronous read and write operations.
FileSystemEventArgs Provides data for the directory events − Changed, Created, Deleted.
FileSystemInfo Provides the base class for both FileInfo and DirectoryInfo objects.
FileSystemWatcher Listens to the file system change notifications and raises events when a directory, or file in a directory, changes.
InternalBufferOverflowException The exception thrown when the internal buffer overflows.
InvalidDataException The exception that is thrown when a data stream is in an invalid format.
IODescriptionAttribute Sets the description visual designers can display when referencing an event, extender, or property.
IOException The exception that is thrown when an I/O error occurs.
MemoryStream Creates a stream whose backing store is memory.
Path Performs operations on String instances that contain file or directory path information. These operations are performed in a cross-platform manner.
PathTooLongException The exception that is thrown when a path or file name is longer than the system-defined maximum length.
PipeException Thrown when an error occurs within a named pipe.
RenamedEventArgs Provides data for the Renamed event.
Stream Provides a generic view of a sequence of bytes. This is an abstract class.
StreamReader Implements a TextReader that reads characters from a byte stream in a particular encoding.
StreamWriter Implements a TextWriter for writing characters to a stream in a particular encoding. To browse the .NET Framework source code for this type, see the Reference Source.
StringReader Implements a TextReader that reads from a string.
StringWriter Implements a TextWriter for writing information to a string. The information is stored in an underlying StringBuilder.
TextReader Represents a reader that can read a sequential series of characters.
TextWriter Represents a writer that can write a sequential series of characters. This class is abstract.
UnmanagedMemoryAccessor Provides random access to unmanaged blocks of memory from managed code.
UnmanagedMemoryStream Provides access to unmanaged blocks of memory from managed code.
WindowsRuntimeStorageExtensions Contains extension methods for the IStorageFile and IStorageFolder interfaces in the Windows Runtime when developing Windows Store apps.
WindowsRuntimeStreamExtensions Contains extension methods for converting between streams in the Windows Runtime and managed streams in the .NET for Windows Store apps.

次の例では、test.txtというファイルを作成し、そこにメッセージを書き込み、ファイルからテキストを読み取り、コンソールに印刷します。

-これを行うために必要なコードの量は驚くほど少ないです!

open System.IO//Name spaces can be opened just as modules
File.WriteAllText("test.txt", "Hello There\n Welcome to:\n Tutorials Point")
let msg = File.ReadAllText("test.txt")
printfn "%s" msg

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Hello There
Welcome to:
Tutorials Point

F#-ジェネリック

ジェネリックを使用すると、プログラムで実際に使用されるまで、クラスまたはメソッドのプログラミング要素のデータ型の指定を遅らせることができます。 つまり、ジェネリックを使用すると、任意のデータ型で機能するクラスまたはメソッドを作成できます。

データ型の代替パラメータを使用して、クラスまたはメソッドの仕様を記述します。 コンパイラは、クラスのコンストラクターまたはメソッドの関数呼び出しを検出すると、特定のデータ型を処理するコードを生成します。

F#では、関数の値、メソッド、プロパティ、およびクラス、レコード、判別された共用体などの集約型は汎用的です。

ジェネリックコンストラクトには、少なくとも1つの型パラメーターが含まれます。 汎用の関数と型を使用すると、型ごとにコードを繰り返すことなく、さまざまな型で機能するコードを作成できます。

構文

ジェネリック構造を記述するための構文は次のとおりです-

//Explicitly generic function.
let function-name<type-parameters> parameter-list =
   function-body

//Explicitly generic method.
[ static ] member object-identifer.method-name<type-parameters> parameter-list [ return-type ] =
   method-body

//Explicitly generic class, record, interface, structure,
//or discriminated union.
type type-name<type-parameters> type-definition

( *Generic Function* )
let printFunc x y =
   printfn "%A, %A" x y

printFunc<float> 10.0 20.0

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

10.0, 20.0

また、単一引用符の構文を使用して関数をジェネリックにすることもできます-

( *Generic Function* )
let printFunction (x: 'a) (y: 'a) =
   printfn "%A %A" x y

printFunction 10.0 20.0

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

10.0 20.0

ジェネリック関数またはメソッドを使用する場合、タイプ引数を指定する必要がない場合があることに注意してください。 ただし、あいまいな場合は、最初の例で行ったように、角括弧で型引数を指定できます。

複数の型がある場合は、複数の型引数をコンマで区切ります。

ジェネリッククラス

ジェネリック関数と同様に、ジェネリッククラスも作成できます。 次の例はこれを示しています-

type genericClass (x: 'a) =
   do printfn "%A" x

let gr = new genericClass<string>("zara")
let gs = genericClass( seq { for i in 1 .. 10 -> (i, i*i) } )

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

"zara"
seq [(1, 1); (2, 4); (3, 9); (4, 16); ...]

F#-デリゲート

デリゲートは、メソッドへの参照を保持する参照型変数です。 参照は実行時に変更できます。 F#デリゲートは、CまたはC ++の関数へのポインターに似ています。

デリゲートの宣言

デリゲート宣言は、デリゲートが参照できるメソッドを決定します。 デリゲートは、デリゲートと同じシグネチャを持つメソッドを参照できます。

デリゲート宣言の構文は-

type delegate-typename = delegate of type1 -> type2

たとえば、デリゲートを考慮してください-

//Delegate1 works with tuple arguments.
type Delegate1 = delegate of (int *int) -> int

//Delegate2 works with curried arguments.
type Delegate2 = delegate of int* int -> int

両方のデリゲートを使用して、2つの_int_パラメーターを持ち、_int_型変数を返すメソッドを参照できます。

構文では-

  • type1 は引数のタイプを表します。
  • type2 は戻り値の型を表します。

注意してください-

  • 引数のタイプは自動的にカリー化されます。
  • デリゲートは、関数値、および静的メソッドまたはインスタンスメソッドに添付できます。
  • F#関数の値は、デリゲートコンストラクターの引数として直接渡すことができます。
  • 静的メソッドの場合、デリゲートはクラスとメソッドの名前を使用して呼び出されます。 インスタンスメソッドの場合、オブジェクトインスタンスとメソッドの名前が使用されます。
  • デリゲート型のInvokeメソッドは、カプセル化された関数を呼び出します。 *また、括弧なしでInvokeメソッド名を参照することにより、デリゲートを関数値として渡すことができます。

次の例は、概念を示しています-

type Myclass() =
   static member add(a : int, b : int) =
      a + b
   static member sub (a : int) (b : int) =
      a - b
   member x.Add(a : int, b : int) =
      a + b
   member x.Sub(a : int) (b : int) =
      a - b

//Delegate1 works with tuple arguments.
type Delegate1 = delegate of (int* int) -> int

//Delegate2 works with curried arguments.
type Delegate2 = delegate of int * int -> int

let InvokeDelegate1 (dlg : Delegate1) (a : int) (b: int) =
   dlg.Invoke(a, b)
let InvokeDelegate2 (dlg : Delegate2) (a : int) (b: int) =
   dlg.Invoke(a, b)

//For static methods, use the class name, the dot operator, and the
//name of the static method.
let del1 : Delegate1 = new Delegate1( Myclass.add )
let del2 : Delegate2 = new Delegate2( Myclass.sub )
let mc = Myclass()

//For instance methods, use the instance value name, the dot operator,
//and the instance method name.

let del3 : Delegate1 = new Delegate1( mc.Add )
let del4 : Delegate2 = new Delegate2( mc.Sub )

for (a, b) in [ (400, 200); (100, 45) ] do
   printfn "%d + %d = %d" a b (InvokeDelegate1 del1 a b)
   printfn "%d - %d = %d" a b (InvokeDelegate2 del2 a b)
   printfn "%d + %d = %d" a b (InvokeDelegate1 del3 a b)
   printfn "%d - %d = %d" a b (InvokeDelegate2 del4 a b)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

400 + 200 = 600
400 - 200 = 200
400 + 200 = 600
400 - 200 = 200
100 + 45 = 145
100 - 45 = 55
100 + 45 = 145
100 - 45 = 55

F#-列挙

列挙は、名前付き整数定数のセットです。

F#では、 enumerationsenums )は、ラベルが値のサブセットに割り当てられる整数型です。 これらをリテラルの代わりに使用して、コードをより読みやすく保守しやすくすることができます。

列挙の宣言

列挙を宣言するための一般的な構文は次のとおりです-

type enum-name =
   | value1 = integer-literal1
   | value2 = integer-literal2
...

次の例は、列挙の使用を示しています-

//Declaration of an enumeration.
type Days =
   | Sun = 0
   | Mon = 1
   | Tues = 2
   | Wed = 3
   | Thurs = 4
   | Fri = 5
   | Sat = 6

//Use of an enumeration.
let weekend1 : Days = Days.Sat
let weekend2 : Days = Days.Sun
let weekDay1 : Days = Days.Mon

printfn "Monday: %A" weekDay1
printfn "Saturday: %A" weekend1
printfn "Sunday: %A" weekend2

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Monday: Mon
Saturday: Sat
Sunday: Sun

F#-パターンマッチング

パターンマッチングを使用すると、「データを1つまたは複数の論理構造と比較したり、データを構成要素に分解したり、さまざまな方法でデータから情報を抽出したりする」ことができます。

言い換えると、一連の条件に対してデータをテストし、満たされた条件に基づいていくつかの計算を実行する、より柔軟で強力な方法を提供します。

概念的には、一連のif…thenステートメントのようなものです。

構文

高レベルの用語では、パターンマッチングはF#でこの構文に従います-

match expr with
| pat1 - result1
| pat2 -> result2
| pat3 when expr2 -> result3
| _ -> defaultResult

どこで、

  • 各|シンボルは条件を定義します。
  • →記号は、「条件が真の場合、この値を返す…​」を意味します。
  • _記号はデフォルトパターンを提供します。つまり、ワイルドカードのような他のすべてのものと一致します。

例1

次の例では、パターン一致構文を使用してフィボナッチ数を計算します-

let rec fib n =
   match n with
   | 0 -> 0
   | 1 -> 1
   | _ -> fib (n - 1) + fib (n - 2)
for i = 1 to 10 do
   printfn "Fibonacci %d: %d" i (fib i)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Fibonacci 1: 1
Fibonacci 2: 1
Fibonacci 3: 2
Fibonacci 4: 3
Fibonacci 5: 5
Fibonacci 6: 8
Fibonacci 7: 13
Fibonacci 8: 21
Fibonacci 9: 34
Fibonacci 10: 55

同じ値を返す複数の条件を連結することもできます。 たとえば-

例2

let printSeason month =
   match month with
   | "December" | "January" | "February" -> printfn "Winter"
   | "March" | "April" -> printfn "Spring"
   | "May" | "June" -> printfn "Summer"
   | "July" | "August" -> printfn "Rainy"
   | "September" | "October" | "November" -> printfn "Autumn"
   | _ -> printfn "Season depends on month!"

printSeason "February"
printSeason "April"
printSeason "November"
printSeason "July"

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Winter
Spring
Autumn
Rainy

パターンマッチング関数

F#では、 function キーワードを使用してパターンマッチング関数を作成できます-

let getRate = function
   | "potato" -> 10.00
   | "brinjal" -> 20.50
   | "cauliflower" -> 21.00
   | "cabbage" -> 8.75
   | "carrot" -> 15.00
   | _ -> nan ( *nan is a special value meaning "not a number"* )

printfn "%g"(getRate "potato")
printfn "%g"(getRate "brinjal")
printfn "%g"(getRate "cauliflower")
printfn "%g"(getRate "cabbage")
printfn "%g"(getRate "carrot")

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

10
20.5
21
8.75
15

パターンへのフィルターまたはガードの追加

*when* キーワードを使用して、フィルターまたはガードをパターンに追加できます。

例1

let sign = function
   | 0 -> 0
   | x when x < 0 -> -1
   | x when x > 0 -> 1

printfn "%d" (sign -20)
printfn "%d" (sign 20)
printfn "%d" (sign 0)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

-1
1
0

例2

let compareInt x =
   match x with
   | (var1, var2) when var1 > var2 -> printfn "%d is greater than %d" var1 var2
   | (var1, var2) when var1 < var2 -> printfn "%d is less than %d" var1 var2
   | (var1, var2) -> printfn "%d equals %d" var1 var2

compareInt (11,25)
compareInt (72, 10)
compareInt (0, 0)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

11 is less than 25
72 is greater than 10
0 equals 0

タプルとのパターンマッチング

次の例は、タプルとのパターンマッチングを示しています-

let greeting (name, subject) =
   match (name, subject) with
   | ("Zara", _) -> "Hello, Zara"
   | (name, "English") -> "Hello, " + name + " from the department of English"
   | (name, _) when subject.StartsWith("Comp") -> "Hello, " + name + " from the department of Computer Sc."
   | (_, "Accounts and Finance") -> "Welcome to the department of Accounts and Finance!"
   | _ -> "You are not registered into the system"

printfn "%s" (greeting ("Zara", "English"))
printfn "%s" (greeting ("Raman", "Computer Science"))
printfn "%s" (greeting ("Ravi", "Mathematics"))

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Hello, Zara
Hello, Raman from the department of Computer Sc.
You are not registered into the system

レコードとのパターンマッチング

次の例は、レコードとのパターンマッチングを示しています-

type Point = { x: float; y: float }
let evaluatePoint (point: Point) =
   match point with
   | { x = 0.0; y = 0.0 } -> printfn "Point is at the origin."
   | { x = xVal; y = 0.0 } -> printfn "Point is on the x-axis. Value is %f." xVal
   | { x = 0.0; y = yVal } -> printfn "Point is on the y-axis. Value is %f." yVal
   | { x = xVal; y = yVal } -> printfn "Point is at (%f, %f)." xVal yVal

evaluatePoint { x = 0.0; y = 0.0 }
evaluatePoint { x = 10.0; y = 0.0 }
evaluatePoint { x = 0.0; y = 10.0 }
evaluatePoint { x = 10.0; y = 10.0 }

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Point is at the origin.
Point is on the x-axis. Value is 10.000000.
Point is on the y-axis. Value is 10.000000.
Point is at (10.000000, 10.000000).

F#-例外処理

例外は、プログラムの実行中に発生する問題です。 F#例外は、ゼロ除算の試行など、プログラムの実行中に発生する例外的な状況への応答です。

例外は、プログラムのある部分から別の部分に制御を移す方法を提供します。 F#の例外処理は、次の構成を提供します-

Construct Description
raise expr Raises the given exception.
failwith expr Raises the *System.Exception *exception.
try expr with rules Catches expressions matching the pattern rules.
try expr finally expr Execution the* finally *expression both when the computation is successful and when an exception is raised.
:? ArgumentException
A rule matching the given .NET exception type.
:? ArgumentException as e A rule matching the given .NET exception type, binding the name* e *to the exception object value.
Failure(msg) → expr
A rule matching the given data-carrying F# exception.
exn → expr A rule matching any exception, binding the name* exn *to the exception object value.
exn when expr → expr

例外処理の基本的な構文から始めましょう。

構文

F#例外処理ブロックの基本的な構文は-

exception exception-type of argument-type

どこで、

  • exception-type は、新しいF#例外タイプの名前です。

  • argument-type は、この型の例外を発生させるときに指定できる引数の型を表します。

  • argument-typeにタプル型を使用して、複数の引数を指定できます。

    *try ... with* 式は、F#言語での例外処理に使用されます。

式を使用したtry…の構文は-

try
   expression1
with
   | pattern1 -> expression2
   | pattern2 -> expression3
...
*try ... finally* 式を使用すると、コードのブロックが例外をスローした場合でも、クリーンアップコードを実行できます。

try…finally式の構文は-

try
   expression1
finally
   expression2
*raise* 関数は、エラーまたは例外条件が発生したことを示すために使用されます。 また、例外オブジェクトのエラーに関する情報もキャプチャします。

raise関数の構文は次のとおりです-

raise (expression)
*failwith* 関数はF#例外を生成します。

failwith関数の構文は-

failwith error-message-string
*invalidArg* 関数は、引数例外を生成します。
invalidArg parameter-name error-message-string

例外処理の例

例1

次のプログラムは、ブロックを使用した単純なtry…による基本的な例外処理を示しています-

let divisionprog x y =
   try
      Some (x/y)
   with
      | :? System.DivideByZeroException -> printfn "Division by zero!"; None

let result1 = divisionprog 100 0

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Division by zero!

例2

F#は、例外を宣言するための exception 型を提供します。 try …​ with 式のフィルターで例外タイプを直接使用できます。

次の例はこれを示しています-

exception Error1 of string
//Using a tuple type as the argument type.
exception Error2 of string * int

let myfunction x y =
   try
      if x = y then raise (Error1("Equal Number Error"))
      else raise (Error2("Error Not detected", 100))
   with
      | Error1(str) -> printfn "Error1 %s" str
      | Error2(str, i) -> printfn "Error2 %s %d" str i
myfunction 20 10
myfunction 5 5

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Error2 Error Not detected 100
Error1 Equal Number Error

実施例3

次の例は、ネストされた例外処理を示しています-

exception InnerError of string
exception OuterError of string

let func1 x y =
   try
      try
         if x = y then raise (InnerError("inner error"))
         else raise (OuterError("outer error"))
      with
         | InnerError(str) -> printfn "Error:%s" str
   finally
      printfn "From the finally block."

let func2 x y =
   try
      func1 x y
   with
      | OuterError(str) -> printfn "Error: %s" str

func2 100 150
func2 100 100
func2 100 120

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

From the finally block.
Error: outer error
Error:inner error
From the finally block.
From the finally block.
Error: outer error

実施例4

次の関数は、 failwith 関数を示しています-

let divisionFunc x y =
   if (y = 0) then failwith "Divisor cannot be zero."
   else
      x/y

let trydivisionFunc x y =
   try
      divisionFunc x y
   with
      | Failure(msg) -> printfn "%s" msg; 0

let result1 = trydivisionFunc 100 0
let result2 = trydivisionFunc 100 4
printfn "%A" result1
printfn "%A" result2

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Divisor cannot be zero.
0
25

実施例5

*invalidArg* 関数は、引数例外を生成します。 次のプログラムはこれを示しています-
let days = [| "Sunday"; "Monday"; "Tuesday"; "Wednesday"; "Thursday"; "Friday"; "Saturday" |]
let findDay day =
   if (day > 7 || day < 1)
      then invalidArg "day" (sprintf "You have entered %d." day)
   days.[day - 1]

printfn "%s" (findDay 1)
printfn "%s" (findDay 5)
printfn "%s" (findDay 9)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Sunday
Thursday
Unhandled Exception:
System.ArgumentException: You have entered 9.
…

システムによっては、システムでエラーの原因となっているファイルと変数に関するその他の情報も表示されます。

F#-クラス

クラスは、プロパティ、メソッド、およびイベントを持つことができるオブジェクトを表す型です。 「これらは、アプリケーションのアクション、プロセス、および概念的なエンティティをモデル化するために使用されます」。

構文

クラスタイプを定義するための構文は次のとおりです-

//Class definition:
type [access-modifier] type-name [type-params] [access-modifier] ( parameter-list ) [ as identifier ] =
   [ class ]
      [ inherit base-type-name(base-constructor-args) ]
      [ let-bindings ]
      [ do-bindings ]
      member-list
      ...
   [ end ]

//Mutually recursive class definitions:
type [access-modifier] type-name1 ...
and [access-modifier] type-name2 ...
...

どこで、

  • type-name は有効な識別子です。 これに対するデフォルトのアクセス修飾子は public です。
  • type-params は、オプションのジェネリック型パラメーターを説明します。
  • parameter-list は、コンストラクタパラメータを記述します。 プライマリコンストラクターのデフォルトのアクセス修飾子は public です。
  • オプションの as キーワードと共に使用される identifier は、インスタンス変数または self-identifier に名前を付けます。これは、型のインスタンスを参照するために型定義で使用できます。
  • inherit キーワードを使用すると、クラスの基本クラスを指定できます。
  • let バインディングを使用すると、クラスに対してローカルなフィールドまたは関数値を宣言できます。
  • do-bindings セクションには、オブジェクトの構築時に実行されるコードが含まれています。
  • member-list は、追加のコンストラクター、インスタンスおよび静的メソッドの宣言、インターフェイス宣言、抽象バインディング、プロパティおよびイベント宣言で構成されます。
  • 定義の開始と終了を示すキーワード classend はオプションです。

クラスのコンストラクター

コンストラクターは、クラス型のインスタンスを作成するコードです。

F#では、コンストラクターは他の.Net言語とほとんど異なる動作をします。 クラス定義では、プライマリコンストラクターの引数はparameter-listとして記述されます。

コンストラクターの本体は、 let および do バインディングで構成されます。

あなたは新しいキーワードを使用してメンバーを追加することにより、追加のコンストラクタを追加することができます-

new (argument-list) = constructor-body

次の例は、概念を示しています-

次のプログラムは、クラスのオブジェクトが作成されている間にラインの長さを計算するコンストラクタとともにラインクラスを作成します-

type Line = class
   val X1 : float
   val Y1 : float
   val X2 : float
   val Y2 : float

   new (x1, y1, x2, y2) as this =
      { X1 = x1; Y1 = y1; X2 = x2; Y2 = y2;}
      then
         printfn " Creating Line: {(%g, %g), (%g, %g)}\nLength: %g"
            this.X1 this.Y1 this.X2 this.Y2 this.Length

   member x.Length =
      let sqr x = x * x
      sqrt(sqr(x.X1 - x.X2) + sqr(x.Y1 - x.Y2) )
end
let aLine = new Line(1.0, 1.0, 4.0, 5.0)

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Creating Line: {(1, 1), (4, 5)}
Length: 5

バインドをしましょう

クラス定義のletバインディングを使用すると、F#クラスのプライベートフィールドとプライベート関数を定義できます。

type Greetings(name) as gr =
   let data = name
   do
      gr.PrintMessage()
   member this.PrintMessage() =
      printf "Hello %s\n" data
let gtr = new Greetings("Zara")

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Hello Zara

_Greetings_クラスに自己識別子_gr_を使用していることに注意してください。

F#-構造

F#の構造体は、値型のデータ型です。 単一の変数を作成し、さまざまなデータ型の関連データを保持するのに役立ちます。 struct キーワードは、構造の作成に使用されます。

構文

構造を定義するための構文は次のとおりです-

[ attributes ]
type [accessibility-modifier] type-name =
   struct
      type-definition-elements
   end
//or
[ attributes ]
[<StructAttribute>]
type [accessibility-modifier] type-name =
   type-definition-elements

2つの構文があります。 struct および end キーワードを使用する場合、 StructAttribute 属性を省略できるため、最初の構文が主に使用されます。

構造定義要素が提供します-

  • メンバーの宣言と定義。
  • コンストラクター、可変および不変フィールド。 *メンバーとインターフェースの実装。

クラスとは異なり、構造体は継承できず、letまたはdoバインディングを含めることはできません。 構造体にはletバインディングがありません。* val *キーワードを使用して、構造体でフィールドを宣言する必要があります。

*val* キーワードを使用してフィールドとそのタイプを定義する場合、フィールド値を初期化することはできず、代わりにゼロまたはnullに初期化されます。 したがって、暗黙のコンストラクターを持つ構造体の場合、 *val* 宣言には *DefaultValue* 属性で注釈が付けられます。

次のプログラムは、コンストラクタとともにライン構造を作成します。 プログラムは、構造を使用して行の長さを計算します-

type Line = struct
   val X1 : float
   val Y1 : float
   val X2 : float
   val Y2 : float

   new (x1, y1, x2, y2) =
      {X1 = x1; Y1 = y1; X2 = x2; Y2 = y2;}
end
let calcLength(a : Line)=
   let sqr a = a * a
   sqrt(sqr(a.X1 - a.X2) + sqr(a.Y1 - a.Y2) )

let aLine = new Line(1.0, 1.0, 4.0, 5.0)
let length = calcLength aLine
printfn "Length of the Line: %g " length

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Length of the Line: 5

F#-オペレーターのオーバーロード

F#で使用可能な組み込み演算子のほとんどを再定義またはオーバーロードできます。 したがって、プログラマはユーザー定義型の演算子も使用できます。

演算子は、括弧で囲まれた特別な名前の関数です。 静的クラスメンバーとして定義する必要があります。 他の関数と同様に、オーバーロードされた演算子には戻り値の型とパラメーターリストがあります。

次の例は、&plus;を示しています。複素数の演算子-

//overloading &plus; operator
static member (&plus;) (a : Complex, b: Complex) =
Complex(a.x &plus; b.x, a.y &plus; b.y)

上記の関数は、ユーザー定義クラスComplexの加算演算子(&plus;)を実装します。 2つのオブジェクトの属性を追加し、結果のComplexオブジェクトを返します。

オペレーターのオーバーロードの実装

次のプログラムは、完全な実装を示しています-

//implementing a complex class with +, and - operators
//overloaded
type Complex(x: float, y : float) =
   member this.x = x
   member this.y = y
  //overloading + operator
   static member (+) (a : Complex, b: Complex) =
      Complex(a.x + b.x, a.y + b.y)

  //overloading - operator
   static member (-) (a : Complex, b: Complex) =
      Complex(a.x - b.x, a.y - b.y)

  //overriding the ToString method
   override this.ToString() =
      this.x.ToString() + " " + this.y.ToString()

//Creating two complex numbers
let c1 = Complex(7.0, 5.0)
let c2 = Complex(4.2, 3.1)

//addition and subtraction using the
//overloaded operators
let c3 = c1 + c2
let c4 = c1 - c2

//printing the complex numbers
printfn "%s" (c1.ToString())
printfn "%s" (c2.ToString())
printfn "%s" (c3.ToString())
printfn "%s" (c4.ToString())

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

7 5
4.2 3.1
11.2 8.1
2.8 1.9

F#-継承

オブジェクト指向プログラミングで最も重要な概念の1つは、継承の概念です。 継承を使用すると、クラスを別のクラスの観点から定義でき、アプリケーションの作成と保守が簡単になります。 これにより、コード機能を再利用して実装時間を短縮することもできます。

クラスを作成するとき、プログラマは完全に新しいデータメンバーとメンバー関数を記述する代わりに、新しいクラスが既存のクラスのメンバーを継承するように指定できます。 この既存のクラスは基本クラスと呼ばれ、新しいクラスは派生クラスと呼ばれます。

継承の概念は、IS-A関係を実装します。 たとえば、哺乳類は動物、犬はIS-A哺乳類、したがって犬はIS-A動物などです。

基本クラスとサブクラス

サブクラスは、すでに定義されている基本クラスから派生します。 サブクラスは、基本クラスのメンバーを継承し、独自のメンバーを持っています。

サブクラスは、以下に示すように inherit キーワードを使用して定義されます-

type MyDerived(...) =
   inherit MyBase(...)

F#では、クラスは最大で1つの直接ベースクラスを持つことができます。 inherit キーワードを使用して基本クラスを指定しない場合、クラスは暗黙的にObjectを継承します。

注意してください-

  • 基本クラスのメソッドとメンバーは、派生クラスの直接メンバーのように、派生クラスのユーザーが利用できます。
  • バインディングとコンストラクターのパラメーターはクラスに対してプライベートであるため、派生クラスからはアクセスできません。
  • キーワード base は、基本クラスのインスタンスを指します。 自己識別子のように使用されます。

type Person(name) =
   member x.Name = name
   member x.Greet() = printfn "Hi, I'm %s" x.Name

type Student(name, studentID : int) =
   inherit Person(name)
   let mutable _GPA = 0.0
   member x.StudentID = studentID
   member x.GPA
      with get() = _GPA
      and set value = _GPA <- value

type Teacher(name, expertise : string) =
   inherit Person(name)

   let mutable _salary = 0.0
   member x.Salary
      with get() = _salary
      and set value = _salary <- value
   member x.Expertise = expertise

//using the subclasses
let p = new Person("Mohan")
let st = new Student("Zara", 1234)
let tr = new Teacher("Mariam", "Java")

p.Greet()
st.Greet()
tr.Greet()

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Hi, I'm Mohan
Hi, I'm Zara
Hi, I'm Mariam

メソッドのオーバーライド

基本クラスメソッドのデフォルトの動作をオーバーライドし、サブクラスまたは派生クラスで異なる方法で実装できます。

F#のメソッドは、デフォルトではオーバーライドできません。

派生クラスのメソッドをオーバーライドするには、次のように abstract および default キーワードを使用してメソッドをオーバーライド可能として宣言する必要があります-

type Person(name) =
   member x.Name = name
   abstract Greet : unit -> unit
   default x.Greet() = printfn "Hi, I'm %s" x.Name

これで、Personクラスの_Greet_メソッドを派生クラスでオーバーライドできます。 次の例はこれを示しています-

type Person(name) =
   member x.Name = name
   abstract Greet : unit -> unit
   default x.Greet() = printfn "Hi, I'm %s" x.Name

type Student(name, studentID : int) =
   inherit Person(name)

   let mutable _GPA = 0.0

   member x.StudentID = studentID
   member x.GPA
      with get() = _GPA
      and set value = _GPA <- value
   override x.Greet() = printfn "Student %s" x.Name

type Teacher(name, expertise : string) =
   inherit Person(name)
   let mutable _salary = 0.0
   member x.Salary
      with get() = _salary
      and set value = _salary <- value

   member x.Expertise = expertise
   override x.Greet() = printfn "Teacher %s." x.Name

//using the subclasses
let p = new Person("Mohan")
let st = new Student("Zara", 1234)
let tr = new Teacher("Mariam", "Java")

//default Greet
p.Greet()

//Overriden Greet
st.Greet()
tr.Greet()

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Hi, I'm Mohan
Student Zara
Teacher Mariam.

抽象クラス

オブジェクトの不完全な実装を提供する必要がある場合がありますが、実際には実装すべきではありません。 後で、他のプログラマーが抽象クラスのサブクラスを作成して完全な実装にする必要があります。

たとえば、学校管理システムではPersonクラスは必要ありません。 ただし、StudentクラスまたはTeacherクラスが必要になります。 このような場合、Personクラスを抽象クラスとして宣言できます。

*AbstractClass* 属性は、クラスにいくつかの抽象メンバーがあることをコンパイラーに伝えます。

クラスが完全に実装されていないため、抽象クラスのインスタンスを作成することはできません。

次の例はこれを示しています-

[<AbstractClass>]
type Person(name) =
   member x.Name = name
   abstract Greet : unit -> unit

type Student(name, studentID : int) =
   inherit Person(name)
   let mutable _GPA = 0.0
   member x.StudentID = studentID
   member x.GPA
      with get() = _GPA
      and set value = _GPA <- value
   override x.Greet() = printfn "Student %s" x.Name

type Teacher(name, expertise : string) =
   inherit Person(name)
   let mutable _salary = 0.0
   member x.Salary
      with get() = _salary
      and set value = _salary <- value
   member x.Expertise = expertise
   override x.Greet() = printfn "Teacher %s." x.Name

let st = new Student("Zara", 1234)
let tr = new Teacher("Mariam", "Java")

//Overriden Greet
st.Greet()
tr.Greet()

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Student Zara
Teacher Mariam.

F#-インターフェース

インターフェイスは、クラスの実装の詳細を記述する抽象的な方法を提供します。 クラスが実装し、公開する必要があるメソッドを宣言するテンプレートです。

構文

インターフェイスは、他のクラスが実装する関連メンバーのセットを指定します。 次の構文があります-

//Interface declaration:
[ attributes ]
type interface-name =
   [ interface ]
      [ inherit base-interface-name ...]
      abstract member1 : [ argument-types1 -> ] return-type1
      abstract member2 : [ argument-types2 -> ] return-type2
      ...
   [ end ]

//Implementing, inside a class type definition:
interface interface-name with
   member self-identifier.member1 argument-list = method-body1
   member self-identifier.member2 argument-list = method-body2
//Implementing, by using an object expression:
[ attributes ]
let class-name (argument-list) =
   { new interface-name with
      member self-identifier.member1 argument-list = method-body1
      member self-identifier.member2 argument-list = method-body2
      [ base-interface-definitions ]
   }
member-list

注意してください-

  • インターフェイス宣言では、メンバーは実装されていません。
  • メンバーは抽象的で、 abstract キーワードによって宣言されます。 ただし、 default キーワードを使用してデフォルトの実装を提供できます。
  • インターフェイスを実装するには、オブジェクト式を使用するか、クラス型を使用します。
  • クラスまたはオブジェクトの実装では、インターフェイスの抽象メソッドのメソッド本体を提供する必要があります。
  • 定義の開始と終了を示すキーワード interfaceend はオプションです。

例えば、

type IPerson =
   abstract Name : string
   abstract Enter : unit -> unit
   abstract Leave : unit -> unit

インターフェイスメソッドの呼び出し

インターフェイスメソッドは、インターフェイスを実装するクラスまたは型のインスタンスではなく、インターフェイスを介して呼び出されます。 インターフェイスメソッドを呼び出すには、*:> *演算子(アップキャスト演算子)を使用してインターフェイスタイプにキャストします。

例えば、

(s :> IPerson).Enter()
(s :> IPerson).Leave()

次の例は、概念を示しています-

type IPerson =
   abstract Name : string
   abstract Enter : unit -> unit
   abstract Leave : unit -> unit

type Student(name : string, id : int) =
   member this.ID = id
   interface IPerson with
      member this.Name = name
      member this.Enter() = printfn "Student entering premises!"
      member this.Leave() = printfn "Student leaving premises!"

type StuffMember(name : string, id : int, salary : float) =
   let mutable _salary = salary

   member this.Salary
      with get() = _salary
      and set(value) = _salary <- value

   interface IPerson with
      member this.Name = name
      member this.Enter() = printfn "Stuff member entering premises!"
      member this.Leave() = printfn "Stuff member leaving premises!"

let s = new Student("Zara", 1234)
let st = new StuffMember("Rohit", 34, 50000.0)

(s :> IPerson).Enter()
(s :> IPerson).Leave()
(st :> IPerson).Enter()
(st :> IPerson).Leave()

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Student entering premises!
Student leaving premises!
Stuff member entering premises!
Stuff member leaving premises!

インターフェースの継承

インターフェイスは、1つ以上のベースインターフェイスから継承できます。

次の例は、概念を示しています-

type Interface1 =
   abstract member doubleIt: int -> int

type Interface2 =
   abstract member tripleIt: int -> int

type Interface3 =
   inherit Interface1
   inherit Interface2
   abstract member printIt: int -> string

type multiplierClass() =
   interface Interface3 with
      member this.doubleIt(a) = 2 *a
      member this.tripleIt(a) = 3* a
      member this.printIt(a) = a.ToString()

let ml = multiplierClass()
printfn "%d" ((ml:>Interface3).doubleIt(5))
printfn "%d" ((ml:>Interface3).tripleIt(5))
printfn "%s" ((ml:>Interface3).printIt(5))

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

10
15
5

F#-イベント

イベントを使用すると、クラス間でメッセージを送受信できます。

GUIでは、イベントはキーを押す、クリックする、マウスの動きなどのユーザーアクション、またはシステムが生成する通知のようなイベントです。 アプリケーションは、発生したイベントに応答する必要があります。 たとえば、割り込み。 イベントはプロセス間通信に使用されます。

オブジェクトは、同期メッセージパッシングを通じて相互に通信します。

イベントは他の機能に関連付けられています。オブジェクトは callback 関数をイベントに登録し、これらのコールバックは、イベントが何らかのオブジェクトによってトリガーされた場合(およびイベントがトリガーされた場合)に実行されます。

イベントクラスとイベントモジュール

Control.Event <'T>クラスは、監視可能なオブジェクトまたはイベントの作成に役立ちます。

それは、イベントを操作するために次のインスタンスメンバーを持っています-

Member Description
Publish Publishes an observation as a first class value.
Trigger Triggers an observation using the given parameters.

Control.Eventモジュールは、イベントストリームを管理するための機能を提供します-

Value Description
add : ('T → unit) → Event<'Del,'T> → unit Runs the given function each time the given event is triggered.
choose : ('T → 'U option) → IEvent<'Del,'T> → IEvent<'U> Returns a new event which fires on a selection of messages from the original event. The selection function takes an original message to an optional new message.
filter : ('T → bool) → IEvent<'Del,'T> → IEvent<'T> Returns a new event that listens to the original event and triggers the resulting event only when the argument to the event passes the given function.
map : ('T → 'U) → IEvent<'Del, 'T> → IEvent<'U> Returns a new event that passes values transformed by the given function.
merge : IEvent<'Del1,'T> → IEvent<'Del2,'T> → IEvent<'T> Fires the output event when either of the input events fire.
pairwise : IEvent<'Del,'T> → IEvent<'T *'T> Returns a new event that triggers on the second and subsequent triggering of the input event. The* Nth triggering of the input event passes the arguments from the N-1th and Nth triggering as a pair. The argument passed to the N-1th triggering is held in hidden internal state until the Nth *triggering occurs.
partition : ('T → bool) → IEvent<'Del,'T> → IEvent<'T>* IEvent<'T> Returns a new event that listens to the original event and triggers the first resulting event if the application of the predicate to the event arguments returned true, and the second event if it returned false.
scan : ('U → 'T → 'U) → 'U → IEvent<'Del,'T> → IEvent<'U> Returns a new event consisting of the results of applying the given accumulating function to successive values triggered on the input event. An item of internal state records the current value of the state parameter. The internal state is not locked during the execution of the accumulation function, so care should be taken that the input IEvent not triggered by multiple threads simultaneously.
split : ('T → Choice<'U1,'U2>) → IEvent<'Del,'T> → IEvent<'U1> * IEvent<'U2> Returns a new event that listens to the original event and triggers the first resulting event if the application of the function to the event arguments returned a Choice1Of2, and the second event if it returns a Choice2Of2.

イベントを作成する

イベントは、 Event クラスを介して作成および使用されます。 イベントコンストラクターは、イベントの作成に使用されます。

type Worker(name : string, shift : string) =
   let mutable _name = name;
   let mutable _shift = shift;
   let nameChanged = new Event<unit>() ( *creates event* )
   let shiftChanged = new Event<unit>() ( *creates event* )

   member this.Name
      with get() = _name
      and set(value) = _name <- value

   member this.Shift
      with get() = _shift
      and set(value) = _shift <- value

この後、リスナーがイベントの Publish プロパティを使用するイベントにフックできるように、nameChangedフィールドをパブリックメンバーとして公開する必要があります-

type Worker(name : string, shift : string) =
   let mutable _name = name;
   let mutable _shift = shift;

   let nameChanged = new Event<unit>() ( *creates event* )
   let shiftChanged = new Event<unit>() ( *creates event* )

   member this.NameChanged = nameChanged.Publish ( *exposed event handler* )
   member this.ShiftChanged = shiftChanged.Publish ( *exposed event handler* )

   member this.Name
      with get() = _name
      and set(value) = _name <- value
      nameChanged.Trigger() ( *invokes event handler* )

   member this.Shift
      with get() = _shift
      and set(value) = _shift <- value
   shiftChanged.Trigger() ( *invokes event handler* )

次に、コールバックをイベントハンドラーに追加します。 各イベントハンドラには、いくつかのメソッドを提供するIEvent <'T>型があります-

Method Description
val Add : event:('T → unit) → unit Connects a listener function to the event. The listener will be invoked when the event is fired.
val AddHandler : 'del → unit Connects a handler delegate object to the event. A handler can be later removed using RemoveHandler. The listener will be invoked when the event is fired.
val RemoveHandler : 'del → unit Removes a listener delegate from an event listener store.

次のセクションでは、完全な例を示します。

次の例は、上記の概念と手法を示しています-

type Worker(name : string, shift : string) =
   let mutable _name = name;
   let mutable _shift = shift;

   let nameChanged = new Event<unit>() ( *creates event* )
   let shiftChanged = new Event<unit>() ( *creates event* )

   member this.NameChanged = nameChanged.Publish ( *exposed event handler* )
   member this.ShiftChanged = shiftChanged.Publish ( *exposed event handler* )

   member this.Name
      with get() = _name
      and set(value) =
         _name <- value
         nameChanged.Trigger() ( *invokes event handler* )

   member this.Shift
      with get() = _shift
      and set(value) =
         _shift <- value
         shiftChanged.Trigger() ( *invokes event handler* )

let wk = new Worker("Wilson", "Evening")
wk.NameChanged.Add(fun () -> printfn "Worker changed name! New name: %s" wk.Name)
wk.Name <- "William"
wk.NameChanged.Add(fun () -> printfn "-- Another handler attached to NameChanged!")
wk.Name <- "Bill"

wk.ShiftChanged.Add(fun () -> printfn "Worker changed shift! New shift: %s" wk.Shift)
wk.Shift <- "Morning"
wk.ShiftChanged.Add(fun () -> printfn "-- Another handler attached to ShiftChanged!")
wk.Shift <- "Night"

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Worker changed name! New name: William
Worker changed name! New name: Bill
-- Another handler attached to NameChanged!
Worker changed shift! New shift: Morning
Worker changed shift! New shift: Night
-- Another handler attached to ShiftChanged!

F#-モジュール

MSDNライブラリによると、F#モジュールは、型、値、関数値、do inバインディングなどのF#コード構成のグループです。 静的メンバーのみを持つ共通言語ランタイム(CLR)クラスとして実装されます。

ファイル全体がモジュールに含まれているかどうかに応じて、モジュール宣言には2種類あります-

  • トップレベルのモジュール宣言
  • ローカルモジュール宣言

最上位のモジュール宣言では、ファイル全体がモジュールに含まれています。 この場合、ファイル内の最初の宣言はモジュール宣言です。 最上位モジュールで宣言をインデントする必要はありません。

ローカルモジュール宣言では、そのモジュール宣言の下でインデントされている宣言のみがモジュールの一部です。

構文

モジュール宣言の構文は次のとおりです-

//Top-level module declaration.
module [accessibility-modifier] [qualified-namespace.]module-name
   declarations

//Local module declaration.
module [accessibility-modifier] module-name =
   declarations

アクセシビリティ修飾子は、パブリック、プライベート、内部のいずれかであることに注意してください。 デフォルトは public です。

次の例は、概念を示します-

例1

モジュールファイルArithmetic.fs-

module Arithmetic
let add x y =
   x + y

let sub x y =
   x - y

let mult x y =
   x * y

let div x y =
   x/y

プログラムファイルmain.fs-

//Fully qualify the function name.
open Arithmetic
let addRes = Arithmetic.add 25 9
let subRes = Arithmetic.sub 25 9
let multRes = Arithmetic.mult 25 9
let divRes = Arithmetic.div 25 9

printfn "%d" addRes
printfn "%d" subRes
printfn "%d" multRes
printfn "%d" divRes

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

34
16
225
2
110
90
1000
10

例2

//Module1
module module1 =
  //Indent all program elements within modules that are declared with an equal sign.
   let value1 = 100
   let module1Function x =
      x + value1

//Module2
module module2 =
   let value2 = 200

  //Use a qualified name to access the function.
  //from module1.
   let module2Function x =
      x + (module1.module1Function value2)

let result = module1.module1Function 25
printfn "%d" result

let result2 = module2.module2Function 25
printfn "%d" result2

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

125
325

F#-名前空間

  • 名前空間*は、ある名前のセットを別の名前のセットから分離する方法を提供するために設計されています。 あるネームスペースで宣言されたクラス名は、別のネームスペースで宣言された同じクラス名と競合しません。

MSDNライブラリごとに、*名前空間*を使用すると、プログラム要素のグループに名前を付けることができるため、コードを関連機能の領域に整理できます。

名前空間の宣言

名前空間でコードを整理するには、ファイルの最初の宣言として名前空間を宣言する必要があります。 ファイル全体の内容は、名前空間の一部になります。

namespace [parent-namespaces.]identifier

次の例は、概念を示しています-

namespace testing

module testmodule1 =
   let testFunction x y =
      printfn "Values from Module1: %A %A" x y
module testmodule2 =
   let testFunction x y =
      printfn "Values from Module2: %A %A" x y

module usermodule =
   do
      testmodule1.testFunction ( "one", "two", "three" ) 150
      testmodule2.testFunction (seq { for i in 1 .. 10 do yield i * i }) 200

あなたがプログラムをコンパイルして実行すると、次の出力が得られます-

Values from Module1: ("one", "two", "three") 150
Values from Module2: seq [1; 4; 9; 16; ...] 200