M.Hiroi's Home Page

F# Programming

お気楽 F# プログラミング超入門

[ Home | C#]

WHAT'S NEW


CONTENTS

お気楽 F# プログラミング超入門と F# Junk Scripts のフォントを Web フォント (Noto Sans JP, Noto Sans Mono) に変更し、印刷用の CSS を追加しました。Web ブラウザの印刷機能を使って PDF に変換することもできます。表示が崩れるときはフォント Noto Sans Mono CJK JP をインストールしてください。


お気楽 F# プログラミング超入門


F# Junk Scripts

M.Hiroi が F# の勉強で書いたジャンクスクリプトです。


はじめに

F# は Microsoft が開発した関数型言語とオブジェクト指向を融合したマルチパラダイムなプログラミング言語です。ベースとなった関数型言語は OCaml です。C# と同じく、共通言語ランタイム (CLR) が解釈する共通中間言語 (CLI) にコンパイルされて実行されます。

F# (や C#) のプログラムを実行するには CLR が必要になりますが、MicroSoft 社が開発していた .NET Framework、オープンソースプロジェクトの .NET Core や Xamarin / Mono は .NET に統合されることになりました。最新版 (2024 年 12 月 時点) は 2024 年 12 月にリリースされた .NET 9.0 ですが、LTS (long-term support) ではありません。本ページでは 2024 年 11 月にリリースされた .NET 8.0 (LTS) を使うことにします。

F# でプログラムを作る場合、.NET SDK をインストールすれば最低限の開発環境が整います。統合開発環境 (Visual Studio など) もありますが、本ページではそれを使わずに、エディタで簡単なプログラムを作りながら、F# の基本を勉強していくことにします。なにぶんにも初心者が作るページなので、勘違いや間違いがあると思います。何かお気づきの点がありましたら、メールでご指摘いただけると助かります。本ページは F# に関する M.Hiroi の「覚え書」にすぎませんが、よろしければお付き合いくださいませ。

●.NET のインストール

.NET の場合、.NET SDK をインストールすれば最低限の開発環境が整うので、C# や F# の学習が目的ならば .NET SDK のほうが簡単かもしれません。.NET SDK は .NET (本家) の Download .NET からダウンロードすることができます。インストールの方法は以下のページに詳しく書かれています。

  1. Windows に .NET をインストールする
  2. Linux に .NET をインストールする
  3. パッケージマネージャを使用せずに Linux に .NET をインストールする

M.Hiroi は 2. に書かれているパッケージマネージャを使って .NET 8.0 を Ubuntu 22.04 (WSL2) にインストールしました。

$ sudo apt install dotnet-sdk-8.0

これだけで、.NET 8.0 がインストールされて、C# と F# を使用できるようになります。

●hello, F#!!

.NET SDK でプログラムを作る場合、dotnet というコマンドラインツール (CLI) を使います。たとえば、コンソールアプリケーションを作成する場合、プログラムを作成するディレクトリ (プロジェクト) で次のコマンドを実行します。

dotnet new console -lang F# [-o name]

dotnet new はプロジェクトを初期化するコマンドです。作成するプログラムの種類 (C# / F# / VB) はオプション -lang で指定することができます。省略した場合は C# になります。これでカレントディレクトリにプログラム (Program.fs) と、プロジェクトに必要なデータが生成されます。ソースファイルの拡張子には fs が使用されます。

また、オプション -o (--output) で作成するプロジェクトを指定することもできます。たとえば、-o hello とするとカレントディレクトリにサブディレクトリ hello が作られて、そこにプロジェクトが生成されます。

プログラムは次のコマンドで実行することができます。

dotnet run [--project name]

オプション --project で実行するプロジェクトを指定します。省略した場合、カレントディレクトリのプロジェクトが実行されます。

簡単な実行例を示しましょう。

$ dotnet new console -lang F# -o hello
テンプレート "コンソール アプリ" が正常に作成されました。

作成後の操作を処理しています...
/home/mhiroi/fsharp/hello/hello.fsproj を復元しています:
  Determining projects to restore...
  Restored /home/mhiroi/fsharp/hello/hello.fsproj (in 3.39 sec).
正常に復元されました。


$ ls hello
Program.fs  hello.fsproj  obj
$ cat hello/Program.fs
// For more information see https://aka.ms/fsharp-console-apps
printfn "Hello from F#"
$ dotnet run --project hello
Hello from F#

実行形式ファイルは次のコマンドで生成します。

dotnet publish  [-c conf]  [project]

project を省略するとカレントディレクトリのプロジェクトが対象となります。オプション -c (--configuration) を省略した場合、デフォルト値の Release が使用され、リリース用の実行形式ファイルが生成されます。Debug を指定すると、デバッグ用の実行形式ファイルが生成されます。

オプション -c は dotnet run でも使用することができます。この場合、ほとんどのプロジェクトでは、-c の既定値は Debug になります。なお、実行形式ファイルを出力するディレクトリはオプション -o (--output) で指定することができます。

簡単な実行例を示しましょう。

$ dotnet publish hello
MSBuild のバージョン 17.8.5+b5265ef37 (.NET)
  Determining projects to restore...
  All projects are up-to-date for restore.
  hello -> /home/mhiroi/fsharp/hello/bin/Release/net8.0/hello.dll
  hello -> /home/mhiroi/fsharp/hello/bin/Release/net8.0/publish/
$ cd hello/bin/Release/net8.0/publish
$ ls
FSharp.Core.dll  de  fr     hello.deps.json  hello.pdb                 it  ko  pt-BR  tr       zh-Hant
cs               es  hello  hello.dll        hello.runtimeconfig.json  ja  pl  ru     zh-Hans
$ ./hello
Hello from F#
$ dotnet hello.dll
Hello from F#

実行形式ファイルの名前は、デフォルトでプロジェクト名と同じになります。プログラムの実行は ./hello のように実行形式ファイルを直接実行するだけではなく、dotnet hello.dll のように dotnet に dll ファイルを渡すことでもできます。

●dotnet fsi

F# を学習する場合、Lisp / Scheme などの関数型言語や Python のような対話モード (REPL) があると便利です。F# の場合、dotnet fsi で対話モード (REPL) を起動することができます。

$ dotnet fsi

Microsoft (R) F# インタラクティブ バージョン F# 8.0 のための 12.8.102.0
Copyright (C) Microsoft Corporation. All rights reserved.

ヘルプを表示するには次を入力してください: #help;;

> 1 + 2;;
val it: int = 3

>

REPL を終了するには #quit;; または CTRL-D を入力してください。

また、dotnet fsi はスクリプト言語のようにプログラム (ソースファイル) を実行することもできます。この場合、ソースファイルの拡張子には .fsx を使うのが習慣のようです。

$ cat hello.fsx
printfn "Hello World!!"

$ dotnet fsi hello.fsx
Hello World!!

本稿では、主に dotnet fsi を使って F# の学習を進めていくことにします。

●簡単なベンチマーク

さて、肝心な F# の実行速度ですが、いつものように「たらいまわし関数」を使って調べてみました。

リスト : たらいまわし関数 (Tak.fsx)

let rec tak x y z =
  if x <= y then z
  else
    tak (tak (x - 1) y z) (tak (y - 1) z x) (tak (z - 1) x y)

関数 tak は OCaml 入門: はじめに で作成したプログラムと同じです。REPL からプログラムを読み込むにはコマンド #load を使います。実行時間は #time で計測することができます。実行結果は次のようになりました。

> #load "Tak.fsx";;
[読み込み中 /home/mhiroi/fsharp/Tak.fsx]
module FSI_0002.Tak
val tak: x: int -> y: int -> z: int -> int

> open Tak;;
> #time;;

--> 今すぐタイミング オン

> tak 22 11 0;;
リアル: 00:00:01.884、CPU: 00:00:02.070、GC 全般0: 0, 全般1: 0, 全般2: 0
val it: int = 11

>
表 : tak(22, 11, 0) の結果
処理系
Python (ver 3.10.12)62.23
Ruby (ver 3.0.2p107)25.59
Lua (ver 5.4.4)22.41
Gauche (ver 0.9.15)21.29
ocamlc (ver 4.13.1)9.46
SBCL (ver 2.1.11)4.90
F# (ver 6.0)1.88
Julia (ver 1.10.5)1.84
SBCL (最適化)1.50
C# (.NET 8.0)1.32
GCC -O2 (ver 11.4.0)1.19
ocamlopt (ver 4.13.1)1.05

F# はネイティブコードにコンパイルするプログラミング言語に匹敵する結果になりました。この結果には M.Hiroi も驚きました。.NET と F# は優秀な処理系だと思います。興味のある方はいろいろ試してみてください。


参考文献・URL

  1. .NET, (本家)
  2. F# Software Foundation, (本家)
  3. F# 関連のドキュメント, (Microsoft Docs)
  4. Midoliy|F#プログラミング, (Midoliy さん)

『お気楽 F# プログラミング超入門』の著作権は筆者「広井誠 (Makoto Hiroi)」が保持します。無断使用や無断転載は禁止いたします。『お気楽 F# プログラミング超入門』で作成したプログラムはフリーソフトウェアとします。ご自由にお使いください。プログラムの改造や配布もご自由にどうぞ。その際は出典を明記してくださるようお願いいたします。

ただし、ドキュメントの内容とプログラムは無保証であり、利用したことにより生じた損害について、作者「広井誠 (Makoto Hiroi)」 は一切の責任を負いません。また、これらのプログラムを販売することで利益を得るといった商行為は禁止いたします。


Copyright (C) 2022-2024 Makoto Hiroi
All rights reserved.

[ Home | C# ]