F#:.NETのための強力な関数型優先言語
第1章:F#の紹介
F#(エフシャープと発音)は、関数型、命令型、オブジェクト指向のパラダイムを組み合わせた多用途のオープンソースプログラミング言語です。Microsoft Researchによって開発され、.NETプラットフォーム上で動作し、表現力、型安全性、パフォーマンスのユニークな組み合わせを提供します。
F#の特徴:
- 関数型プログラミング
- 型推論
- 簡潔な構文
- .NETプラットフォームとの互換性
簡単な「Hello, World!」プログラムから始めましょう:
printfn "こんにちは、世界!"
第2章:基本的な型と値
F#はさまざまなデータ型をサポートしています。整数、浮動小数点数、文字列、ブール値などを見てみましょう:
let integerNumber = 42
let floatingPointNumber = 3.14
let text = "F#は素晴らしい言語です"
let isAwesome = true
printfn "整数: %d" integerNumber
printfn "浮動小数点数: %f" floatingPointNumber
printfn "文字列: %s" text
printfn "真偽値: %b" isAwesome
第3章:関数
F#では関数がファーストクラスの市民です。円の面積を計算する簡単な関数を作成してみましょう:
let calculateCircleArea radius =
let pi = System.Math.PI
pi * radius * radius
let area = calculateCircleArea 5.0
printfn "円の面積: %.2f" area
第4章:パターンマッチング
パターンマッチングは、F#でデータ構造を分解するための強力な機能です:
let describeNumber n =
match n with
| 0 -> "ゼロです"
| x when x < 0 -> "負の数です"
| x when x % 2 = 0 -> "偶数です"
| _ -> "正の奇数です"
printfn "%d: %s" 0 (describeNumber 0)
printfn "%d: %s" -5 (describeNumber -5)
printfn "%d: %s" 4 (describeNumber 4)
printfn "%d: %s" 7 (describeNumber 7)
第5章:リストとシーケンス
F#はコレクションを扱うための強力なツールを提供します:
let numbers = [1; 2; 3; 4; 5]
let squares = List.map (fun x -> x * x) numbers
printfn "元のリスト: %A" numbers
printfn "二乗したリスト: %A" squares
let evenNumbers = List.filter (fun x -> x % 2 = 0) numbers
printfn "偶数のみ: %A" evenNumbers
第6章:再帰
再帰はF#でアルゴリズムを表現する自然な方法です:
let rec factorial n =
match n with
| 0 | 1 -> 1
| _ -> n * factorial (n - 1)
let result = factorial 5
printfn "5の階乗: %d" result
第7章:判別共用体
判別共用体を使用すると、複数のケースを持つ型を定義できます:
type Shape =
| Circle of radius: float
| Rectangle of width: float * height: float
| Triangle of base': float * height: float
let calculateArea shape =
match shape with
| Circle radius -> System.Math.PI * radius * radius
| Rectangle (width, height) -> width * height
| Triangle (base', height) -> 0.5 * base' * height
let circleArea = calculateArea (Circle 5.0)
let rectangleArea = calculateArea (Rectangle(4.0, 3.0))
let triangleArea = calculateArea (Triangle(6.0, 4.0))
printfn "円の面積: %.2f" circleArea
printfn "長方形の面積: %.2f" rectangleArea
printfn "三角形の面積: %.2f" triangleArea
第8章:レコード型
レコード型を使用すると、名前付きフィールドを持つ構造化されたデータを作成できます:
type Person = { Name: string; Age: int; City: string }
let alice = { Name = "Alice"; Age = 30; City = "東京" }
let bob = { Name = "Bob"; Age = 25; City = "大阪" }
let printPerson person =
printfn "%s (%d歳) - %s在住" person.Name person.Age person.City
printPerson alice
printPerson bob
第9章:オプション型
オプション型は値の不在を扱うのに役立ちます:
let divideIfEven numerator denominator =
if denominator % 2 = 0 then
Some(numerator / denominator)
else
None
let printResult result =
match result with
| Some value -> printfn "結果: %d" value
| None -> printfn "計算できません"
printResult (divideIfEven 10 4)
printResult (divideIfEven 10 3)
第10章:非同期プログラミング
F#は非同期プログラミングを簡単にします:
open System
open System.Net.Http
let fetchWebPageAsync (url: string) = async {
use client = new HttpClient()
let! response = client.GetStringAsync(url) |> Async.AwaitTask
return response.Substring(0, 100) // 最初の100文字
}
let websites = [
"https://fsharp.org";
"https://docs.microsoft.com/ja-jp/dotnet/fsharp/";
]
let fetchAllPages = async {
let! results = websites |> List.map fetchWebPageAsync |> Async.Parallel
for (url, content) in List.zip websites results do
printfn "%s: %s..." url content
}
Async.RunSynchronously fetchAllPages
第11章:単位of measure
F#では数値型に単位を追加できます:
[<Measure>] type m
[<Measure>] type s
let distance = 100.0<m>
let time = 9.58<s>
let speed = distance / time
printfn "速度: %.2f m/s" speed
// 変換
[<Measure>] type km
[<Measure>] type h
let kmPerHour = (speed * 3600.0<s/h>) / 1000.0<m/km>
printfn "速度: %.2f km/h" kmPerHour
第12章:型プロバイダー
型プロバイダーを使用すると、外部データソースに簡単にアクセスできます:
#r "nuget: FSharp.Data"
open FSharp.Data
type Weather = JsonProvider<"https://api.openweathermap.org/data/2.5/weather?q=Tokyo&appid=YOUR_API_KEY">
let getWeather city =
let apiKey = "YOUR_API_KEY"
let url = sprintf "https://api.openweathermap.org/data/2.5/weather?q=%s&appid=%s" city apiKey
let weather = Weather.Load(url)
printfn "%s の天気:" city
printfn "気温: %.1f°C" (weather.Main.Temp - 273.15)
printfn "湿度: %d%%" weather.Main.Humidity
printfn "天気: %s" weather.Weather.[0].Description
getWeather "Tokyo"
第13章:計算式
計算式を使用すると、カスタムの制御フローを定義できます:
type MaybeBuilder() =
member this.Bind(x, f) =
match x with
| None -> None
| Some a -> f a
member this.Return(x) = Some x
let maybe = MaybeBuilder()
let divideBy bottom top =
if bottom = 0 then None
else Some(top / bottom)
let result = maybe {
let! a = divideBy 2 10
let! b = divideBy 2 a
return b
}
match result with
| Some value -> printfn "結果: %d" value
| None -> printfn "計算できません"
第14章:オブジェクト指向プログラミング
F#はオブジェクト指向プログラミングの概念をサポートしています:
type Animal(name: string) =
member this.Name = name
abstract member MakeSound : unit -> string
type Dog(name: string) =
inherit Animal(name)
override this.MakeSound() = "ワンワン"
type Cat(name: string) =
inherit Animal(name)
override this.MakeSound() = "ニャーニャー"
let animals = [
Dog("ポチ") :> Animal;
Cat("タマ") :> Animal
]
for animal in animals do
printfn "%s: %s" animal.Name (animal.MakeSound())
第15章:Giraffeを使用したWeb開発
F#はWeb開発にも使用できます。以下はGiraffeフレームワークを使用した簡単な例です:
#r "nuget: Giraffe"
#r "nuget: Microsoft.AspNetCore.App"
open System
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Hosting
open Microsoft.Extensions.Hosting
open Giraffe
let webApp =
choose [
route "/" >=> text "F#とGiraffeへようこそ!"
route "/hello" >=> bindQuery<string option> (fun name ->
match name with
| Some n -> text (sprintf "こんにちは、%s!" n)
| None -> text "こんにちは、ゲスト!"
)
]
[<EntryPoint>]
let main _ =
Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(
fun webHostBuilder ->
webHostBuilder
.Configure(fun app -> app.UseGiraffe webApp)
.Build()
.Run())
この包括的なガイドでは、F#プログラミングのさまざまな側面を基本的な概念から高度な機能まで網羅しています。各章にはコード例と説明が含まれており、学習者がF#の用語と概念を理解するのに役立ちます。これらの例を通じて学習することで、F#プログラミングの堅固な基礎を身につけ、より複雑なプロジェクトに取り組む準備が整います。