SlideShare ist ein Scribd-Unternehmen logo
1 von 21
Downloaden Sie, um offline zu lesen
Scala 初心者が Hom 函手を Scala で考えてみた
Pre-ScalaMatsuri 2020
高瀬 和之
@Guvalif
>=> 自己紹介
- 名前: 高瀬 和之 (たかせ かずゆき)
- 所属: Chatwork 株式会社 @大阪
- 専門:
- フロントエンド開発
(React / Redux / TypeScript)
- ティーチング
(アルゴリズム / 機械学習 / 数学
/ 組み込みシステム)
- ひとこと:
- Scala のイベントは初めてです 💪
2
>=> アジェンダ
1. ことの発端
2. そもそも函手とは?
3. Hom 函手
4. Scala での実装例
3
01ことの発端
>=> ある日のひとまく
Scala ガチ勢の H 氏 < Haskell 書けるらしいじゃん? Scala もいけるっしょ 💪
たかせ < えっ?
~ 数週間後 ~
- 私に送られてきたのは…
- State Monad ゴリゴリで,
- for 式をいい感じに駆使していて,
- Files changed が 18 くらいある,
- そんな Pull-Request 😇🎉
5
>=> とはいえ…
- 意外とがんばれば読める
- for 式 ⇒ Haskell の do 構文
- Monad ⇒ Haskell の屋台骨
- case class ⇒ Haskell の Record っぽさ
- trait ⇒ Haskell の型クラスっぽさ
- etc...
かくして、”Do Haskell for Scala” という標語が、生まれたとかなんとか…
(※フロントエンド開発メンバーとの日常会話にて)
6
>=> 問題点 🙅‍♂
- なんとなく読める ≠ 使いこなせる
- Scala の言語仕様をきちんと理解した上で、モナモナできるようになりたい!
というわけで…
1. まずはファンクタファンクタできるように、型クラス周りの仕様を知る
2. 何か適当な Functor を実装してみる
こうして私は Scala に入門しました 🚪
7
02そもそも函手とは?
~ 圏論への招待 ~
>=> 圏論ことはじめ (1):対象と射
- 圏論の材料
- 対象 ⇒ 点
- 射 ⇒ 点から点を結ぶ矢印 (点と点の関連性を表す)
- ここまでの事実 ⇒ なんか有向グラフっぽい
9
>=> 圏論ことはじめ (2):圏の例
- しりとりの圏 (対象:ひらがな,射:単語)
10
- 型と関数の圏 (対象:型,射:関数)
り ご ら ぱ り
りんご ごりら らっぱ ぱせり
String Int
Boolean
length
isEven
isCamelCase
>=> 圏論ことはじめ (3):函手 / Functor
- ある圏から、グラフ構造を全て抜き出す
- 別の圏にて、グラフ構造が一致する箇所に対応づける
- 対象と対象の対応関係,および射と射の対応関係,その2つ組と考えてもよい
(※実際には公理を満たすように,かつ実用的に必要な性質を盛り込んで考えます)
11
圏 D圏 C
03Hom 函手
>=> Hom 函手ことはじめ (1):Hom 集合
- 圏論では、ある対象 ● から別の対象 ● へ、複数の射が存在してもよい
- すなわち、射の集合を考えることができる ⇒ Hom 集合と呼ぶ
- 対象 ● から対象 ● に関する Hom 集合 ⇒ Hom(●, ●) と表す
- 下図の場合:
- Hom(●, ●) = { a, b, c, d, e }
- Hom(●, ●) = ∅
13
a
e
d
b
c
>=> Hom 函手ことはじめ (2):舞台を集合の圏へ
- 圏 C で何か1つ対象を固定する (今回は X)
- 固定した対象と、圏 C の任意の対象に関して、Hom 集合を取る
14
X
A
D C
B
圏 C 集合の圏
Hom(X, A)
Hom(X, B)
Hom(X, C)
※Hom(X, D) は空集合
>=> Hom 函手ことはじめ (3):Hom 集合の間に射が存在する条件
- 対象 X から対象 A への任意の射 a
- 対象 X から対象 B へのある射 b
- これらに対して、b = f ∘ a を満たす射 f が存在すること
(※ b を使って X から B へ向かうことと、a と f を使って X から B へ向かうことが等しくなる,の意)
15
X
B
A
圏 C 集合の圏
Hom(X, A)
Hom(X, B)
∀a
∃b
∃f, b = f ∘ a
f ∘ _
>=> Hom 函手ことはじめ (4):共変 Hom 函手
- 共変 Hom 函手とは:
- 任意の圏から集合の圏への函手であって,
- 対象 * を対象 Hom(X, *) へ移し,
- (制約を満たす) 射 f を射 f ∘ _ へ移す,そんな函手
16
X
B
A
圏 C 集合の圏
Hom(X, A)
Hom(X, B)
∀a
∃b
∃f, b = f ∘ a
f ∘ _
04Scala での実装例
>=> 共変 Hom 函手 in Scala
- 型と関数の圏をベースに、Scala 圏を考えると:
- * → Hom(X, *) なる対象の対応は、カインド X => * として表現できる
(※厳密には、指数対象というものを考えて、Hom 集合を Scala 圏に埋め込むとそうなります)
- f → f ∘ _ なる射の対応は、高階関数 f => f compose _ として表現できる
18
X
B
A
Scala 圏 Scala 圏
X => A
X => B
∀a
∃b
∃f, b = f compose a
f compose _
>=> 実際にやってみた
// F[_] が対象の対応関係を,map が射の対応関係を表す
trait EndoFunctor[F[_]] {
def map[A, B](f: A => B): F[A] => F[B]
}
type X = Unit // 固定する型は何でも良いが、今回は Unit 型
type Xto[Y] = X => Y // Hom 函手における、対象の対応関係
implicit val homFunctor = new EndoFunctor[Xto] {
def map[A, B](f: A => B): Xto[A] => Xto[B] = // Hom 函手における、射の対応関係
f compose _
}
// 任意の函手の実装を用いて、射を相手先の圏へ移す(※といいつつ Scala 圏には閉じてるので、Endo = 自己)
def map[F[_], A, B](f: A => B)(implicit functor: EndoFunctor[F]): F[A] => F[B] =
functor.map(f)
19
>=> 実際につかってみた
val f: Int => String = x => s"String($x)" // Int と String を結ぶ射をピックアップ
val Fa: Xto[Int] = x => 0 // Hom(X, Int) から、要素をピックアップ
// 1. Hom(X, Int) の要素 Fa
// 2. Hom 集合を結ぶ射 map(f)
// これらから、Hom(X, String) の要素 Fb を導出
val Fb: Xto[String] = map(f).apply(Fa)
println(Fb(())) // String(0) と表示される
20
- 実装してみての感想:
- 高階カインドは、やはりあると表現力が高い 🎉
- implicit parameter は、auto capturing default parameter だと思った 🤔
- 本当は map(f).apply(Fa) の部分を、map(f)(Fa) と書けたらかっちょよい
ちなみに…
Chatwork では、社内勉強会で圏論なんかも取り扱っているらしいですよ 👍

Weitere ähnliche Inhalte

Was ist angesagt?

距離と分類の話
距離と分類の話距離と分類の話
距離と分類の話考司 小杉
 
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたってTsuyoshi Matsudate
 
数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由Hiromi Ishii
 
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...NTT DATA Technology & Innovation
 
Polyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGAPolyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGAryos36
 
TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?Mr. Vengineer
 
よくわかるCoqプログラミング
よくわかるCoqプログラミングよくわかるCoqプログラミング
よくわかるCoqプログラミングReal_analysis
 
機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)Kota Matsui
 
macOSの仮想化技術について ~Virtualization-rs Rust bindings for virtualization.framework ~
macOSの仮想化技術について ~Virtualization-rs Rust bindings for virtualization.framework ~macOSの仮想化技術について ~Virtualization-rs Rust bindings for virtualization.framework ~
macOSの仮想化技術について ~Virtualization-rs Rust bindings for virtualization.framework ~NTT Communications Technology Development
 
大規模分散システムの現在 -- Twitter
大規模分散システムの現在 -- Twitter大規模分散システムの現在 -- Twitter
大規模分散システムの現在 -- Twittermaruyama097
 
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)lestrrat
 
機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門hoxo_m
 
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021Kouhei Sutou
 
Scapyで作る・解析するパケット
Scapyで作る・解析するパケットScapyで作る・解析するパケット
Scapyで作る・解析するパケットTakaaki Hoyo
 
Elasticsearch as a Distributed System
Elasticsearch as a Distributed SystemElasticsearch as a Distributed System
Elasticsearch as a Distributed SystemSatoyuki Tsukano
 
ブースティング入門
ブースティング入門ブースティング入門
ブースティング入門Retrieva inc.
 
ペアプロするならgit-duetを使おう
ペアプロするならgit-duetを使おうペアプロするならgit-duetを使おう
ペアプロするならgit-duetを使おうShinya Nakajima
 

Was ist angesagt? (20)

距離と分類の話
距離と分類の話距離と分類の話
距離と分類の話
 
これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたって
 
数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由数学プログラムを Haskell で書くべき 6 の理由
数学プログラムを Haskell で書くべき 6 の理由
 
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
JavaでCPUを使い倒す! ~Java 9 以降の CPU 最適化を覗いてみる~(NTTデータ テクノロジーカンファレンス 2019 講演資料、2019...
 
Polyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGAPolyphony: Python ではじめる FPGA
Polyphony: Python ではじめる FPGA
 
圏とHaskellの型
圏とHaskellの型圏とHaskellの型
圏とHaskellの型
 
TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?TensorFlow XLAは、 中で何をやっているのか?
TensorFlow XLAは、 中で何をやっているのか?
 
よくわかるCoqプログラミング
よくわかるCoqプログラミングよくわかるCoqプログラミング
よくわかるCoqプログラミング
 
機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)機械学習による統計的実験計画(ベイズ最適化を中心に)
機械学習による統計的実験計画(ベイズ最適化を中心に)
 
macOSの仮想化技術について ~Virtualization-rs Rust bindings for virtualization.framework ~
macOSの仮想化技術について ~Virtualization-rs Rust bindings for virtualization.framework ~macOSの仮想化技術について ~Virtualization-rs Rust bindings for virtualization.framework ~
macOSの仮想化技術について ~Virtualization-rs Rust bindings for virtualization.framework ~
 
大規模分散システムの現在 -- Twitter
大規模分散システムの現在 -- Twitter大規模分散システムの現在 -- Twitter
大規模分散システムの現在 -- Twitter
 
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
GoらしいAPIを求める旅路 (Go Conference 2018 Spring)
 
機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門機械学習のためのベイズ最適化入門
機械学習のためのベイズ最適化入門
 
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
Apache Arrow Flight – ビッグデータ用高速データ転送フレームワーク #dbts2021
 
Scapyで作る・解析するパケット
Scapyで作る・解析するパケットScapyで作る・解析するパケット
Scapyで作る・解析するパケット
 
Elasticsearch as a Distributed System
Elasticsearch as a Distributed SystemElasticsearch as a Distributed System
Elasticsearch as a Distributed System
 
計算可能実数とは
計算可能実数とは計算可能実数とは
計算可能実数とは
 
ブースティング入門
ブースティング入門ブースティング入門
ブースティング入門
 
Rの高速化
Rの高速化Rの高速化
Rの高速化
 
ペアプロするならgit-duetを使おう
ペアプロするならgit-duetを使おうペアプロするならgit-duetを使おう
ペアプロするならgit-duetを使おう
 

Ähnlich wie Scala 初心者が Hom 函手を Scala で考えてみた

How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜Hiromi Ishii
 
Asakusa FrameworkとScalaの密かな関係
Asakusa FrameworkとScalaの密かな関係Asakusa FrameworkとScalaの密かな関係
Asakusa FrameworkとScalaの密かな関係hishidama
 
Introduction to Spray at Kansai Functional Programming
Introduction to Spray at Kansai Functional ProgrammingIntroduction to Spray at Kansai Functional Programming
Introduction to Spray at Kansai Functional ProgrammingSuguru Hamazaki
 
Scala.jsはじめました?
Scala.jsはじめました?Scala.jsはじめました?
Scala.jsはじめました?K Kinzal
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックスTomoharu ASAMI
 
Gaucheでマクロを書こう
Gaucheでマクロを書こうGaucheでマクロを書こう
Gaucheでマクロを書こうHideaki Nagamine
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8y_taka_23
 
オブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programmingオブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional ProgrammingTomoharu ASAMI
 
ScalaプログラマのためのHaskell入門
ScalaプログラマのためのHaskell入門ScalaプログラマのためのHaskell入門
ScalaプログラマのためのHaskell入門Yasuaki Takebe
 
並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.js並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.jsYoshiiro Ueno
 

Ähnlich wie Scala 初心者が Hom 函手を Scala で考えてみた (11)

How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 
Asakusa FrameworkとScalaの密かな関係
Asakusa FrameworkとScalaの密かな関係Asakusa FrameworkとScalaの密かな関係
Asakusa FrameworkとScalaの密かな関係
 
Introduction to Spray at Kansai Functional Programming
Introduction to Spray at Kansai Functional ProgrammingIntroduction to Spray at Kansai Functional Programming
Introduction to Spray at Kansai Functional Programming
 
Scala.jsはじめました?
Scala.jsはじめました?Scala.jsはじめました?
Scala.jsはじめました?
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックス
 
Gaucheでマクロを書こう
Gaucheでマクロを書こうGaucheでマクロを書こう
Gaucheでマクロを書こう
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
 
オブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programmingオブジェクト指向開発におけるObject-Functional Programming
オブジェクト指向開発におけるObject-Functional Programming
 
ScalaプログラマのためのHaskell入門
ScalaプログラマのためのHaskell入門ScalaプログラマのためのHaskell入門
ScalaプログラマのためのHaskell入門
 
並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.js並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.js
 
Hokuriku Scala 1
Hokuriku Scala 1Hokuriku Scala 1
Hokuriku Scala 1
 

Scala 初心者が Hom 函手を Scala で考えてみた

  • 1. Scala 初心者が Hom 函手を Scala で考えてみた Pre-ScalaMatsuri 2020 高瀬 和之 @Guvalif
  • 2. >=> 自己紹介 - 名前: 高瀬 和之 (たかせ かずゆき) - 所属: Chatwork 株式会社 @大阪 - 専門: - フロントエンド開発 (React / Redux / TypeScript) - ティーチング (アルゴリズム / 機械学習 / 数学 / 組み込みシステム) - ひとこと: - Scala のイベントは初めてです 💪 2
  • 3. >=> アジェンダ 1. ことの発端 2. そもそも函手とは? 3. Hom 函手 4. Scala での実装例 3
  • 5. >=> ある日のひとまく Scala ガチ勢の H 氏 < Haskell 書けるらしいじゃん? Scala もいけるっしょ 💪 たかせ < えっ? ~ 数週間後 ~ - 私に送られてきたのは… - State Monad ゴリゴリで, - for 式をいい感じに駆使していて, - Files changed が 18 くらいある, - そんな Pull-Request 😇🎉 5
  • 6. >=> とはいえ… - 意外とがんばれば読める - for 式 ⇒ Haskell の do 構文 - Monad ⇒ Haskell の屋台骨 - case class ⇒ Haskell の Record っぽさ - trait ⇒ Haskell の型クラスっぽさ - etc... かくして、”Do Haskell for Scala” という標語が、生まれたとかなんとか… (※フロントエンド開発メンバーとの日常会話にて) 6
  • 7. >=> 問題点 🙅‍♂ - なんとなく読める ≠ 使いこなせる - Scala の言語仕様をきちんと理解した上で、モナモナできるようになりたい! というわけで… 1. まずはファンクタファンクタできるように、型クラス周りの仕様を知る 2. 何か適当な Functor を実装してみる こうして私は Scala に入門しました 🚪 7
  • 9. >=> 圏論ことはじめ (1):対象と射 - 圏論の材料 - 対象 ⇒ 点 - 射 ⇒ 点から点を結ぶ矢印 (点と点の関連性を表す) - ここまでの事実 ⇒ なんか有向グラフっぽい 9
  • 10. >=> 圏論ことはじめ (2):圏の例 - しりとりの圏 (対象:ひらがな,射:単語) 10 - 型と関数の圏 (対象:型,射:関数) り ご ら ぱ り りんご ごりら らっぱ ぱせり String Int Boolean length isEven isCamelCase
  • 11. >=> 圏論ことはじめ (3):函手 / Functor - ある圏から、グラフ構造を全て抜き出す - 別の圏にて、グラフ構造が一致する箇所に対応づける - 対象と対象の対応関係,および射と射の対応関係,その2つ組と考えてもよい (※実際には公理を満たすように,かつ実用的に必要な性質を盛り込んで考えます) 11 圏 D圏 C
  • 13. >=> Hom 函手ことはじめ (1):Hom 集合 - 圏論では、ある対象 ● から別の対象 ● へ、複数の射が存在してもよい - すなわち、射の集合を考えることができる ⇒ Hom 集合と呼ぶ - 対象 ● から対象 ● に関する Hom 集合 ⇒ Hom(●, ●) と表す - 下図の場合: - Hom(●, ●) = { a, b, c, d, e } - Hom(●, ●) = ∅ 13 a e d b c
  • 14. >=> Hom 函手ことはじめ (2):舞台を集合の圏へ - 圏 C で何か1つ対象を固定する (今回は X) - 固定した対象と、圏 C の任意の対象に関して、Hom 集合を取る 14 X A D C B 圏 C 集合の圏 Hom(X, A) Hom(X, B) Hom(X, C) ※Hom(X, D) は空集合
  • 15. >=> Hom 函手ことはじめ (3):Hom 集合の間に射が存在する条件 - 対象 X から対象 A への任意の射 a - 対象 X から対象 B へのある射 b - これらに対して、b = f ∘ a を満たす射 f が存在すること (※ b を使って X から B へ向かうことと、a と f を使って X から B へ向かうことが等しくなる,の意) 15 X B A 圏 C 集合の圏 Hom(X, A) Hom(X, B) ∀a ∃b ∃f, b = f ∘ a f ∘ _
  • 16. >=> Hom 函手ことはじめ (4):共変 Hom 函手 - 共変 Hom 函手とは: - 任意の圏から集合の圏への函手であって, - 対象 * を対象 Hom(X, *) へ移し, - (制約を満たす) 射 f を射 f ∘ _ へ移す,そんな函手 16 X B A 圏 C 集合の圏 Hom(X, A) Hom(X, B) ∀a ∃b ∃f, b = f ∘ a f ∘ _
  • 18. >=> 共変 Hom 函手 in Scala - 型と関数の圏をベースに、Scala 圏を考えると: - * → Hom(X, *) なる対象の対応は、カインド X => * として表現できる (※厳密には、指数対象というものを考えて、Hom 集合を Scala 圏に埋め込むとそうなります) - f → f ∘ _ なる射の対応は、高階関数 f => f compose _ として表現できる 18 X B A Scala 圏 Scala 圏 X => A X => B ∀a ∃b ∃f, b = f compose a f compose _
  • 19. >=> 実際にやってみた // F[_] が対象の対応関係を,map が射の対応関係を表す trait EndoFunctor[F[_]] { def map[A, B](f: A => B): F[A] => F[B] } type X = Unit // 固定する型は何でも良いが、今回は Unit 型 type Xto[Y] = X => Y // Hom 函手における、対象の対応関係 implicit val homFunctor = new EndoFunctor[Xto] { def map[A, B](f: A => B): Xto[A] => Xto[B] = // Hom 函手における、射の対応関係 f compose _ } // 任意の函手の実装を用いて、射を相手先の圏へ移す(※といいつつ Scala 圏には閉じてるので、Endo = 自己) def map[F[_], A, B](f: A => B)(implicit functor: EndoFunctor[F]): F[A] => F[B] = functor.map(f) 19
  • 20. >=> 実際につかってみた val f: Int => String = x => s"String($x)" // Int と String を結ぶ射をピックアップ val Fa: Xto[Int] = x => 0 // Hom(X, Int) から、要素をピックアップ // 1. Hom(X, Int) の要素 Fa // 2. Hom 集合を結ぶ射 map(f) // これらから、Hom(X, String) の要素 Fb を導出 val Fb: Xto[String] = map(f).apply(Fa) println(Fb(())) // String(0) と表示される 20 - 実装してみての感想: - 高階カインドは、やはりあると表現力が高い 🎉 - implicit parameter は、auto capturing default parameter だと思った 🤔 - 本当は map(f).apply(Fa) の部分を、map(f)(Fa) と書けたらかっちょよい