Hちょびよみ勉強ノート(4 〜 7回目)

ブログ書くのむっちゃサボってる…。

多相の種類

polymorphism ┬ universal(静的) ┬ parametric(ジェネリクス)
             │                 └ inclusion(サブタイプ) ┬ nominal(継承)
             │                                          └ structural(ダックタイピング)
             └ ad-hoc(実行時)  ┬ overloading(オーバーロード)
                                └ coercion(暗黙の型変換)

OCamlにはoverloading多相は無いらしいので完全な型推論が出来るらしい。

型推論の完全性
def f(x, y) = x + y 
↑
↓
def f(x: Int, y: Int): Int = x + y

が相互に完全に求まること

カリー化

他引数関数を1引数関数のチェーンにすること

(a, b, c) -> d
  ↓
a -> (b -> (c -> d))

カリー化すると何が嬉しい?

  • 関数が取り回しやすくなる
  • ラムダ計算界隈の話に載せられるようになる
ラムダ計算
  • 変数
  • 1引数関数
  • 適用

で全ての計算を行う体系。チューリング完全

カタモーフィズム

「Listはfoldrだ」

  • List(データ構造)
    • cons*1(a1, cons(a2, cons(a3, ..., cons(an, nil()) ... )
  • foldr(処理構造)
    • f(a1, f(a2, f(a3, ..., f(an, zero) ... )

なんか構造が似ている気がする。

似ている?

Listの定義(Aは型変数)

List<A> : Nil | cons(A, List<A>)  # Nilか任意の値とリストの組
nil     : () -> Nil
cons    : A × List<A> -> List<A> # 任意の値とリストの組でリストにする
head    : A × List<A> -> A       # 任意の値とリストの組から先頭の要素を取り出す
tail    : A × List<A> -> List<A> # 任意の値とリストの組から先頭以外のリストを取り出す
isnil   : List<A> -> Boolean      # リストがnilかどうか

tailやheadが組になってるのは要素が最低1はあるってことを言いたいのかな?

folrの定義(AとBは型変数)

f              : A × B -> B
zero           : Nil -> B
foldr(f, zero) : List<A> -> B

似ている。

List cons : A × List -> List nil : () -> Nil
foldr f : A × B -> B zero : Nil -> B

List

  cons
  /\
a1  cons
     /\
   a2  cons
        /\
       a3   nil

foldr

   f
  /\
a1    f
     /\
   a2    f
        /\
      a3   zero

似ている*2

ListはF始代数*3

foldrの最も汎用的な形がList*4

foldrの始対象がList*5

ListはF代数の圏におけるF始代数*6

List                              foldr
  cons                                f
  /\                               /\
a1  cons                            a1   f
     /\     <------ 抽象的 ------     /\
   a2  cons   - 関数(射)が作れそう->  a2    f
        /\                               /\
      a3   nil                            a3  zero
可換図式*7

何を書いているのか分からねーと思うが僕も何を書いているのかわからない。

     List<A>   =   Nil | A × List<A>
foldr↓                 ↓ id | id × foldr(f, zero)
      B       ←   Nil | A × B
          (ex, sum)

良くどころか完全に分からないんだけど、結局のところ何故foldrがListの様に見えるのかというと上の図の下向き矢印に当たる関数が存在するから、とのこと…。

とにかく、代数的データ型(F代数の構造を持つもの→右側が再帰している構造のもの)のうち最も汎用的なもの(始代数)がListであり、代数的データ型であればfoldrが出来る、という事?
Optionは要素数が0か1のList、Eitherは要素数が2固定のListという風にみなせるらしい。

要するに

ルノアールで2時間聞いただけで理解できるはずがなかった

*1:コンスセルって言って組を作るやつとの事

*2:右側が再帰している構造

*3:この辺りでもう脳は限界を迎えていた

*4:foldrは右が関数だけどListは何でもいい

*5:「始」は最もシンプル、汎用的なという意味らしい。対象とは「何かしらのモノ」の事

*6:脳みそが限界を越えた。F代数という話題の中で最もシンプルな代数。代数って何や…。代数 extends 対象との事らしいけれども

*7:アバッ…アッ…アバッーッ