SlideShare ist ein Scribd-Unternehmen logo
1 von 21
F#のすすめ
静的型付け言語と動的型付け言語
 静的型付けとは?
 型が決定するのはコンパイル時
 パフォーマンスは高め
 記述は比較的面倒くさくなる
 例
 C#
 Java
 動的型付けとは?
 型が決定するのは実行時
 パフォーマンスは低め
 その代わりお手軽
 例
 Python
 JavaScript
 そもそも「型」って何よ?
 真剣に語りだすと本が一冊書けるレベル
 あとあんまり詳しくない🙄
 なのでざっくり行きます。
静的型付け言語と動的型付け言語
 静的型付き言語の一つ C#の場合
静的型付け言語と動的型付け言語
using System.Collections.Generic;
using System.Linq;
using static System.Console;
namespace Sample
{
class Program
{
private static void Main()
{
if (!int.TryParse(ReadLine(), out int n)) return;
IEnumerable<int> numbers = Enumerable.Range(1, n);
int sumOfOdds = numbers.Where((int x) => { return x % 2 != 0; }).Sum();
WriteLine(sumOfOdds);
}
}
}
 動的型付き言語の一つ Rubyの場合
静的型付け言語と動的型付け言語
s = gets.chomp
exit if s =~ /D/
numbers = 1..s.to_i
sum_of_odds = numbers.select(&:odd?).sum
puts sum_of_odds
C# に比べて
めっちゃお手軽
 動的型付き言語の一つ Python と JavaScript の場合
静的型付け言語と動的型付け言語
try:
n = int(input())
except ValueError:
exit()
numbers = (x + 1 for x in range(0, n))
sum_of_odds = sum(x for x in numbers if x % 2)
print(sum_of_odds)
process.stdin.on('data', chunk => {
const n = +chunk.toString();
if (Number.isNaN(n)) return;
const numbers = Array.from({ length: n }, (_, i) => i + 1);
const sumOfOdds = numbers.filter(x => x % 2).reduce((a, b) => a + b);
console.log(sumOfOdds);
});
静的型付け言語と動的型付け言語
 なぜこんなにも記述量に差があるのか。
 型が明示されていて、その分コード量が増える。
 ただし、コードに型が明示されるということは、後から読んだときに分かりやすいということでもある。
 C# はたまたまクラスベースの言語であり、クラスの宣言も必要だった。
 加えて名前空間の宣言も省略していなかった。
 ※ C# Scripts (csx) を使うと名前空間やクラスの宣言が不要になるので、Rubyのコードとほとんど変わらなくなる。
型推論という仕組みがある
 コードの文脈に沿って、その式の型を明示しなくても型が一意に決まる機能
 つまり動的型付け言語では無縁の機能
private static void Main()
{
if (!int.TryParse(ReadLine(), out var n)) return;
var numbers = Enumerable.Range(1, 10);
var sumOfOdds = numbers.Where(x => x % 2 != 0).Sum();
WriteLine(sumOfOdds);
}
private static void Main()
{
if (!int.TryParse(ReadLine(), out int n)) return;
IEnumerable<int> numbers = Enumerable.Range(1, 10);
int sumOfOdds = numbers.Where((int x) => { return x % 2 != 0; }).Sum();
WriteLine(sumOfOdds);
}
型推論を活用すればコードがどんどん短くなるのでは??
そこで F# ですよ
 F# の場合
let n =
match System.Int32.TryParse(stdin.ReadLine()) with
| false, _ -> exit 1
| true, n -> n
let numbers = [1 .. n]
let sumOfOdds = numbers |> List.filter (fun x -> x % 2 <> 0) |> List.sum
printfn "%d" sumOfOdds
Q. あんまり他と変わってなくない?
A. すみません、例が悪かったです。
次は F# の型推論の強力さに
スポットしていきます。
※ 対比として C# のコードも載せます。
F# の型推論
open System.Collections.Generic
let list = List()
list.Add 1
list.Add 5
list.Add "abc" // ← コンパイルエラー
using System.Collections.Generic;
var list = new List<int>();
list.Add(1);
list.Add(5);
list.Add("abc"); // ← コンパイルエラー
public interface IMixed { }
public class Int : IMixed
{
public int Value { get; }
public Int(int value) => Value = value;
public void Deconstruct(out int n) => n = Value;
}
public class Str : IMixed
{
public string Value { get; }
public Str(string value) => Value = value;
public void Deconstruct(out string s) => s = Value;
}
var list = new List<IMixed>();
list.Add(new Int(1));
list.Add(new Int(5));
list.Add(new Str("abc"));
foreach (var x in list)
{
Console.WriteLine(x switch
{
Int(var n) => $"[{n}]",
Str(var s) => $""{s}"",
_ => throw new ArgumentException(),
});
}
数字と文字列両方持てる配列を定義したいこともあるよね
type Mixed = Int of int | Str of string
let list = ResizeArray ()
list.Add <| Int 1
list.Add <| Int 5
list.Add <| Str "abc"
list
|> Seq.iter (function
| Int n -> printfn "[%d]" n
| Str s -> printfn ""%s"" s)
using System;
using System.Collections.Generic;
var list = new List<object>();
list.Add(1);
list.Add(5);
list.Add("abc");
foreach (var x in list)
{
switch (x)
{
case int n:
Console.WriteLine($"[{n}]");
break;
case string s:
Console.WriteLine($""{s}"");
break;
}
}
let f x =
match x with
| 1 -> "One"
| 2 -> "Two"
| 3 -> "Three"
| _ -> "More"
let g = function
| 1 -> "One"
| 2 -> "Two"
| 3 -> "Three"
| _ -> "More"
bool f(int x)
{
switch (x)
{
case 1: return "One";
case 2: return "Two";
case 3: return "Three";
default: return "More";
}
}
F# の型推論
let inline parseOpt input =
let mutable x = Unchecked.defaultof<_>
let succeeded = (^a : (static member TryParse : string * ^a byref -> bool) (input, &x))
if succeeded then Some x else None
parseOpt "123"
|> Option.iter (printfn "%d")
parseOpt "123"
|> Option.iter (printfn "%f")
if (int.TryParse("123", out var i))
{
Console.WriteLine(i);
}
if (double.TryParse("123", out var d))
{
Console.WriteLine(d);
}
 FizzBuzz
 基本ルール
 通常 1 から 100 までの数字を数え上げて出力するだけ
 ただし !
 3 の倍数のときには、数字を出力する代わりに "Fizz" と出力する
 5 の倍数のときには、数字を出力する代わりに "Buzz" と出力する
 15 の倍数のときには、数字を出力する代わりに "FizzBuzz" と出力する
みなさんもやってみませんか?
let fizzBuzz n =
match n % 3, n % 5 with
| 0, 0 -> "FizzBuzz"
| 0, _ -> "Fizz"
| _, 0 -> "Buzz"
| _, _ -> string n
[1 .. 100]
|> List.map fizzBuzz
|> List.iter (printfn "%s")
fizzBuzz :: Int -> String
fizzBuzz n =
case (n `mod` 3, n `mod` 5) of
(0, 0) -> "FizzBuzz"
(0, _) -> "Fizz"
(_, 0) -> "Buzz"
(_, _) -> show n
main :: IO ()
main = mapM_ (putStrLn <$> fizzBuzz) [1 .. 100]
const fizzBuzz = n => {
if (n % 15 === 0) return 'FizzBuzz';
if (n % 3 === 0) return 'Fizz';
if (n % 5 === 0) return 'Buzz';
return String(n);
};
for (const s of Array.from({ length: 100 }, (_, i) => i + 1)) {
console.log(fizzBuzz(s));
}
def fizz_buzz n
s = ''
s << 'Fizz' if (n % 3).zero?
s << 'Buzz' if (n % 5).zero?
s.empty? ? n.to_s : s
end
(1 .. 100).each do |n|
puts fizz_buzz n
end
def fizz_buzz(n):
if n % 15 == 0:
return "FizzBuzz"
elif n % 3 == 0:
return "Fizz"
elif n % 5 == 0:
return "Buzz"
else:
return str(n)
for s in (fizz_buzz(n) for n in range(1, 101)):
print(s)
type FizzBuzzResult = Num of int | Fizz | Buzz | FizzBuzz
let fbResultToString = function Num n -> string n | r -> string r
let (|Num|Fizz|Buzz|FizzBuzz|) n =
match n % 3, n % 5 with
| 0, 0 -> FizzBuzz
| 0, _ -> Fizz
| _, 0 -> Buzz
| _, _ -> Num n
let fizzBuzz = function
| Num n -> Num n
| Fizz -> Fizz
| Buzz -> Buzz
| FizzBuzz -> FizzBuzz
[1 .. 100]
|> List.map (fizzBuzz >> fbResultToString)
|> List.iter (printfn "%s")

Weitere ähnliche Inhalte

Was ist angesagt?

テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式digitalghost
 
PCさえあればいい。
PCさえあればいい。PCさえあればいい。
PCさえあればいい。bleis tift
 
Elixirだ 第1回 - 基礎だ -
Elixirだ 第1回 - 基礎だ -Elixirだ 第1回 - 基礎だ -
Elixirだ 第1回 - 基礎だ -Joe_noh
 
言語処理系入門4
言語処理系入門4言語処理系入門4
言語処理系入門4Kenta Hattori
 
Elixirだ 第1回強化版 後半
Elixirだ 第1回強化版 後半Elixirだ 第1回強化版 後半
Elixirだ 第1回強化版 後半Joe_noh
 
Elixirだ 第2回
Elixirだ 第2回Elixirだ 第2回
Elixirだ 第2回Joe_noh
 
Elixirだ 第1回強化版 前半
Elixirだ 第1回強化版 前半Elixirだ 第1回強化版 前半
Elixirだ 第1回強化版 前半Joe_noh
 
ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体digitalghost
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門kwatch
 
知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数Wataru Terada
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるHideyuki Tanaka
 
お前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのかお前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのかKousuke Ebihara
 
40分濃縮 PHP classの教室
40分濃縮 PHP classの教室40分濃縮 PHP classの教室
40分濃縮 PHP classの教室Yusuke Ando
 
PHP基本的関数QUIZ
PHP基本的関数QUIZPHP基本的関数QUIZ
PHP基本的関数QUIZWataru Terada
 
traitを使って楽したい話
traitを使って楽したい話traitを使って楽したい話
traitを使って楽したい話infinite_loop
 
PHP classの教室
PHP classの教室PHP classの教室
PHP classの教室Yusuke Ando
 
Java電卓勉強会資料
Java電卓勉強会資料Java電卓勉強会資料
Java電卓勉強会資料Toshio Ehara
 

Was ist angesagt? (20)

テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式テンプレートメタプログラミング as 式
テンプレートメタプログラミング as 式
 
PCさえあればいい。
PCさえあればいい。PCさえあればいい。
PCさえあればいい。
 
Elixirだ 第1回 - 基礎だ -
Elixirだ 第1回 - 基礎だ -Elixirだ 第1回 - 基礎だ -
Elixirだ 第1回 - 基礎だ -
 
言語処理系入門4
言語処理系入門4言語処理系入門4
言語処理系入門4
 
Elixirだ 第1回強化版 後半
Elixirだ 第1回強化版 後半Elixirだ 第1回強化版 後半
Elixirだ 第1回強化版 後半
 
Elixirだ 第2回
Elixirだ 第2回Elixirだ 第2回
Elixirだ 第2回
 
Elixirだ 第1回強化版 前半
Elixirだ 第1回強化版 前半Elixirだ 第1回強化版 前半
Elixirだ 第1回強化版 前半
 
勉強会課題①
勉強会課題①勉強会課題①
勉強会課題①
 
ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体
 
Rust samurai#01
Rust samurai#01Rust samurai#01
Rust samurai#01
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
 
知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数知ってるようで意外と知らないPHPの便利関数
知ってるようで意外と知らないPHPの便利関数
 
C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
 
お前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのかお前は PHP の歴史的な理由の数を覚えているのか
お前は PHP の歴史的な理由の数を覚えているのか
 
40分濃縮 PHP classの教室
40分濃縮 PHP classの教室40分濃縮 PHP classの教室
40分濃縮 PHP classの教室
 
CLR/H No.35-2
CLR/H No.35-2CLR/H No.35-2
CLR/H No.35-2
 
PHP基本的関数QUIZ
PHP基本的関数QUIZPHP基本的関数QUIZ
PHP基本的関数QUIZ
 
traitを使って楽したい話
traitを使って楽したい話traitを使って楽したい話
traitを使って楽したい話
 
PHP classの教室
PHP classの教室PHP classの教室
PHP classの教室
 
Java電卓勉強会資料
Java電卓勉強会資料Java電卓勉強会資料
Java電卓勉強会資料
 

Ähnlich wie F#のすすめ

プログラミング・パラダイム
プログラミング・パラダイムプログラミング・パラダイム
プログラミング・パラダイムYusuke Matsushita
 
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューAkira Inoue
 
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)Google Developer Relations Team
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
F#によるFunctional Programming入門
F#によるFunctional Programming入門F#によるFunctional Programming入門
F#によるFunctional Programming入門bleis tift
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Ransui Iso
 
Material
MaterialMaterial
Material_TUNE_
 
Unity C#3からC#6に向けて
Unity C#3からC#6に向けてUnity C#3からC#6に向けて
Unity C#3からC#6に向けてonotchi_
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Springanyakichi
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-Kazunari Hara
 
20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swiftnecocen
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座bleis tift
 
VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門kamukiriri
 
こわくない型クラス
こわくない型クラスこわくない型クラス
こわくない型クラスKota Mizushima
 
関数プログラミング ことはじめ (再)
関数プログラミング ことはじめ (再)関数プログラミング ことはじめ (再)
関数プログラミング ことはじめ (再)Suguru Hamazaki
 
Xtend30分クッキング やきに駆動
Xtend30分クッキング   やきに駆動Xtend30分クッキング   やきに駆動
Xtend30分クッキング やきに駆動Shinichi Kozake
 
Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418Uehara Junji
 

Ähnlich wie F#のすすめ (20)

プログラミング・パラダイム
プログラミング・パラダイムプログラミング・パラダイム
プログラミング・パラダイム
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービュー
 
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
Google Developer Day 2010 Japan: プログラミング言語 Go (鵜飼 文敏)
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
F#によるFunctional Programming入門
F#によるFunctional Programming入門F#によるFunctional Programming入門
F#によるFunctional Programming入門
 
Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2Lisp tutorial for Pythonista : Day 2
Lisp tutorial for Pythonista : Day 2
 
Material
MaterialMaterial
Material
 
Unity C#3からC#6に向けて
Unity C#3からC#6に向けてUnity C#3からC#6に向けて
Unity C#3からC#6に向けて
 
Refactoring point of Kotlin application
Refactoring point of Kotlin applicationRefactoring point of Kotlin application
Refactoring point of Kotlin application
 
Python standard 2022 Spring
Python standard 2022 SpringPython standard 2022 Spring
Python standard 2022 Spring
 
速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-速くなければスマフォじゃない - インターンバージョン-
速くなければスマフォじゃない - インターンバージョン-
 
20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift
 
Python opt
Python optPython opt
Python opt
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座
 
VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門VS勉強会 .NET Framework 入門
VS勉強会 .NET Framework 入門
 
こわくない型クラス
こわくない型クラスこわくない型クラス
こわくない型クラス
 
関数プログラミング ことはじめ (再)
関数プログラミング ことはじめ (再)関数プログラミング ことはじめ (再)
関数プログラミング ことはじめ (再)
 
Xtend30分クッキング やきに駆動
Xtend30分クッキング   やきに駆動Xtend30分クッキング   やきに駆動
Xtend30分クッキング やきに駆動
 
Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418Shibuya JVM Groovy 20150418
Shibuya JVM Groovy 20150418
 

F#のすすめ

  • 2. 静的型付け言語と動的型付け言語  静的型付けとは?  型が決定するのはコンパイル時  パフォーマンスは高め  記述は比較的面倒くさくなる  例  C#  Java  動的型付けとは?  型が決定するのは実行時  パフォーマンスは低め  その代わりお手軽  例  Python  JavaScript
  • 3.  そもそも「型」って何よ?  真剣に語りだすと本が一冊書けるレベル  あとあんまり詳しくない🙄  なのでざっくり行きます。 静的型付け言語と動的型付け言語
  • 4.  静的型付き言語の一つ C#の場合 静的型付け言語と動的型付け言語 using System.Collections.Generic; using System.Linq; using static System.Console; namespace Sample { class Program { private static void Main() { if (!int.TryParse(ReadLine(), out int n)) return; IEnumerable<int> numbers = Enumerable.Range(1, n); int sumOfOdds = numbers.Where((int x) => { return x % 2 != 0; }).Sum(); WriteLine(sumOfOdds); } } }
  • 5.  動的型付き言語の一つ Rubyの場合 静的型付け言語と動的型付け言語 s = gets.chomp exit if s =~ /D/ numbers = 1..s.to_i sum_of_odds = numbers.select(&:odd?).sum puts sum_of_odds C# に比べて めっちゃお手軽
  • 6.  動的型付き言語の一つ Python と JavaScript の場合 静的型付け言語と動的型付け言語 try: n = int(input()) except ValueError: exit() numbers = (x + 1 for x in range(0, n)) sum_of_odds = sum(x for x in numbers if x % 2) print(sum_of_odds) process.stdin.on('data', chunk => { const n = +chunk.toString(); if (Number.isNaN(n)) return; const numbers = Array.from({ length: n }, (_, i) => i + 1); const sumOfOdds = numbers.filter(x => x % 2).reduce((a, b) => a + b); console.log(sumOfOdds); });
  • 7. 静的型付け言語と動的型付け言語  なぜこんなにも記述量に差があるのか。  型が明示されていて、その分コード量が増える。  ただし、コードに型が明示されるということは、後から読んだときに分かりやすいということでもある。  C# はたまたまクラスベースの言語であり、クラスの宣言も必要だった。  加えて名前空間の宣言も省略していなかった。  ※ C# Scripts (csx) を使うと名前空間やクラスの宣言が不要になるので、Rubyのコードとほとんど変わらなくなる。
  • 8. 型推論という仕組みがある  コードの文脈に沿って、その式の型を明示しなくても型が一意に決まる機能  つまり動的型付け言語では無縁の機能 private static void Main() { if (!int.TryParse(ReadLine(), out var n)) return; var numbers = Enumerable.Range(1, 10); var sumOfOdds = numbers.Where(x => x % 2 != 0).Sum(); WriteLine(sumOfOdds); } private static void Main() { if (!int.TryParse(ReadLine(), out int n)) return; IEnumerable<int> numbers = Enumerable.Range(1, 10); int sumOfOdds = numbers.Where((int x) => { return x % 2 != 0; }).Sum(); WriteLine(sumOfOdds); }
  • 11.  F# の場合 let n = match System.Int32.TryParse(stdin.ReadLine()) with | false, _ -> exit 1 | true, n -> n let numbers = [1 .. n] let sumOfOdds = numbers |> List.filter (fun x -> x % 2 <> 0) |> List.sum printfn "%d" sumOfOdds
  • 13. 次は F# の型推論の強力さに スポットしていきます。 ※ 対比として C# のコードも載せます。
  • 14. F# の型推論 open System.Collections.Generic let list = List() list.Add 1 list.Add 5 list.Add "abc" // ← コンパイルエラー using System.Collections.Generic; var list = new List<int>(); list.Add(1); list.Add(5); list.Add("abc"); // ← コンパイルエラー
  • 15. public interface IMixed { } public class Int : IMixed { public int Value { get; } public Int(int value) => Value = value; public void Deconstruct(out int n) => n = Value; } public class Str : IMixed { public string Value { get; } public Str(string value) => Value = value; public void Deconstruct(out string s) => s = Value; } var list = new List<IMixed>(); list.Add(new Int(1)); list.Add(new Int(5)); list.Add(new Str("abc")); foreach (var x in list) { Console.WriteLine(x switch { Int(var n) => $"[{n}]", Str(var s) => $""{s}"", _ => throw new ArgumentException(), }); } 数字と文字列両方持てる配列を定義したいこともあるよね type Mixed = Int of int | Str of string let list = ResizeArray () list.Add <| Int 1 list.Add <| Int 5 list.Add <| Str "abc" list |> Seq.iter (function | Int n -> printfn "[%d]" n | Str s -> printfn ""%s"" s) using System; using System.Collections.Generic; var list = new List<object>(); list.Add(1); list.Add(5); list.Add("abc"); foreach (var x in list) { switch (x) { case int n: Console.WriteLine($"[{n}]"); break; case string s: Console.WriteLine($""{s}""); break; } } let f x = match x with | 1 -> "One" | 2 -> "Two" | 3 -> "Three" | _ -> "More" let g = function | 1 -> "One" | 2 -> "Two" | 3 -> "Three" | _ -> "More" bool f(int x) { switch (x) { case 1: return "One"; case 2: return "Two"; case 3: return "Three"; default: return "More"; } }
  • 16. F# の型推論 let inline parseOpt input = let mutable x = Unchecked.defaultof<_> let succeeded = (^a : (static member TryParse : string * ^a byref -> bool) (input, &x)) if succeeded then Some x else None parseOpt "123" |> Option.iter (printfn "%d") parseOpt "123" |> Option.iter (printfn "%f") if (int.TryParse("123", out var i)) { Console.WriteLine(i); } if (double.TryParse("123", out var d)) { Console.WriteLine(d); }
  • 17.  FizzBuzz  基本ルール  通常 1 から 100 までの数字を数え上げて出力するだけ  ただし !  3 の倍数のときには、数字を出力する代わりに "Fizz" と出力する  5 の倍数のときには、数字を出力する代わりに "Buzz" と出力する  15 の倍数のときには、数字を出力する代わりに "FizzBuzz" と出力する
  • 19. let fizzBuzz n = match n % 3, n % 5 with | 0, 0 -> "FizzBuzz" | 0, _ -> "Fizz" | _, 0 -> "Buzz" | _, _ -> string n [1 .. 100] |> List.map fizzBuzz |> List.iter (printfn "%s") fizzBuzz :: Int -> String fizzBuzz n = case (n `mod` 3, n `mod` 5) of (0, 0) -> "FizzBuzz" (0, _) -> "Fizz" (_, 0) -> "Buzz" (_, _) -> show n main :: IO () main = mapM_ (putStrLn <$> fizzBuzz) [1 .. 100]
  • 20. const fizzBuzz = n => { if (n % 15 === 0) return 'FizzBuzz'; if (n % 3 === 0) return 'Fizz'; if (n % 5 === 0) return 'Buzz'; return String(n); }; for (const s of Array.from({ length: 100 }, (_, i) => i + 1)) { console.log(fizzBuzz(s)); } def fizz_buzz n s = '' s << 'Fizz' if (n % 3).zero? s << 'Buzz' if (n % 5).zero? s.empty? ? n.to_s : s end (1 .. 100).each do |n| puts fizz_buzz n end def fizz_buzz(n): if n % 15 == 0: return "FizzBuzz" elif n % 3 == 0: return "Fizz" elif n % 5 == 0: return "Buzz" else: return str(n) for s in (fizz_buzz(n) for n in range(1, 101)): print(s)
  • 21. type FizzBuzzResult = Num of int | Fizz | Buzz | FizzBuzz let fbResultToString = function Num n -> string n | r -> string r let (|Num|Fizz|Buzz|FizzBuzz|) n = match n % 3, n % 5 with | 0, 0 -> FizzBuzz | 0, _ -> Fizz | _, 0 -> Buzz | _, _ -> Num n let fizzBuzz = function | Num n -> Num n | Fizz -> Fizz | Buzz -> Buzz | FizzBuzz -> FizzBuzz [1 .. 100] |> List.map (fizzBuzz >> fbResultToString) |> List.iter (printfn "%s")