Step 3 ユーザーからの入力を受け取りint型に変換
Step 2 ではletを使った変数宣言とprintfnを使った出力について学んだ。Step 3 ではユーザーからの入力を受け取りそれを整数型に変換する方法を学ぶ。
ユーザーからの入力
F#でユーザーからの入力を受け取るにはSystem.Console.ReadLine()関数を使用する。この関数はユーザーがコンソールに入力した文字列を返す。
またConsole.ReadLine()の代わりにstdin.ReadLine()を使用することもできる。stdinは F#の組み込みオブジェクトで標準入力を表す。
let inputString = stdin.ReadLine()stdin.ReadLine()はstring型(文字列型)の値を返す。
inputStringの型は型推論によりstring型になる。
文字列から整数への変換
stdin.ReadLine()で取得した文字列を数当てゲームで使用するためには、整数に変換する必要がある。
文字列を整数に変換するにはSystem.Int32.Parse()関数を使用する。
またInt32.Parse()の糖衣構文としてint関数も用意されているので今回はこちらを使用しよう。
let inputNumber = Int32.Parse(inputString)// 以下のようにも書けるlet inputNumber2 = int inputStringinputStringに"42"のような数字の文字列が格納されているとinputNumberとinputNumber2には42という整数の値が入る。
Int32.Parse()やint関数はint型の値を返す。
inputNumberとinputNumber2の型は型推論によりint型になる。
これらを明示的にint型と宣言しても良いが今回は型推論に任せよう。
パイプ演算子|>を使った簡潔な記述
先ほどのコードでは、ユーザーからの入力を一旦inputStringという変数に格納し、その後でinputNumberに変換していた。
let inputString = stdin.ReadLine()let inputNumber = int inputStringF#の特徴の一つである「パイプ演算子|>」を使うとこの処理をより簡潔に記述できる。パイプ演算子は左側の値を右側の関数に渡す役割を果たす。
let inputNumber = stdin.ReadLine() |> intこのコードではstdin.ReadLine()で得られた文字列が|>によってint関数に直接渡されその結果がinputNumberに格納される。中間の変数inputStringが不要になり、コードがスッキリした。
パイプ演算子の動作
|>は左辺の値(ここではstdin.ReadLine()の結果である文字列)を右辺の関数(ここではint)の第一引数として渡す。つまり以下の 2 つのコードは実質的に同じ意味になる。
// パイプ演算子を使わない場合let inputNumber = int (stdin.ReadLine())
// パイプ演算子を使う場合let inputNumber = stdin.ReadLine() |> intパイプ演算子を使うことでデータの流れを左から右へと視覚的に表現できる。これは関数型プログラミングにおける「関数合成」の考え方に基づいている。
パイプ演算子の利点
パイプ演算子を使う主な利点は以下の通りだ。
- コードの可読性が向上する:データの流れが明確になり処理の意図が理解しやすくなる。
- 中間の変数名を考える必要がなくなる:特に、一度しか使わない変数名を省略できるため、コードが簡潔になる。
- 関数合成が容易になる:複数の関数を組み合わせた処理を簡潔に記述できる。
パイプ演算子の使用例: addとmultiply
パイプ演算子の便利さを示す別の例として簡単な数値計算を考えてみよう。
まず 2 つの数を加算する関数addと 2 つの数を乗算する関数multiplyを定義する。
let add x y = x + ylet multiply x y = x * yこれらの関数を使って、まず 2 つの数を加算し、その結果に別の数を乗算する計算を考えてみる。
パイプ演算子を使わない場合
let a = 3let b = 5let c = 2
let sum = add a blet result = multiply sum cprintfn "計算結果: %d" result // 出力: 計算結果: 16パイプ演算子を使う場合
let a = 3let b = 5let c = 2
let result = a |> add b |> multiply cprintfn "計算結果: %d" result // 出力: 計算結果: 16この例ではaをadd bに渡しその結果をmultiply cに渡している。パイプ演算子を使うことで計算の流れがより明確になり一時的な変数sumを作る必要がなくなる。
この例のようにパイプ演算子は複数の関数を組み合わせてデータを変換していく際に特に効果を発揮する。関数型プログラミングではこのような関数の合成によって複雑な処理を表現することが一般的だ。
Program.fsへの適用 (パイプ演算子使用版)
パイプ演算子を使用してProgram.fsを書き換えてみよう。
let answer = 42printfn "正解は%dです" answer
printfn "1から100までの数字を入力してください。"let inputNumber = stdin.ReadLine() |> int
printfn "あなたが入力した数字は%dです。" inputNumberこの変更は、見た目上はわずかだがパイプ演算子を使うことでデータの流れがより明確になり、F#らしいコードに一歩近づいた。
まとめ
このステップでは以下の内容を学んだ。
stdin.ReadLine()関数を使ったユーザーからの入力の受け取りInt32.Parse()関数int関数を使った文字列から整数への変換- パイプ演算子
|>を使った処理の簡潔な記述
次のステップでは、ユーザーが入力した値が正解かどうかを判定するロジックを実装する。