Subscribed unsubscribe Subscribe Subscribe

ろじかるんるんものがたり

病人が特に何も書かない。無駄だからだ。

Scala勉強会第 162 回で発表してきたので補足とか

Programming Scala

表題のとおり。スライドはこちら。今回はスライドだけ見て分かるように発表資料を作らなかったので、見ても意味不明だと思います。

以下発表の補足。というか言い訳です…

 

rpscala でツイッター検索したら Free Monad が云々という文字列を見かけたので、Free について何かしら発表しようと決めました。

Free Monad については有名所だと、

Haskell for all: Why free monads matter

等で解説されています。記事タイトルは why functional programming matter のオマージュですね。日本語の情報も適当に検索すれば沢山出てくると思います。

ただ、前述の記事を読んですぐ分かる人はそれなりに知識ある人だと思うのです。そういう人は放っておいてもいい。使い方は分かったけれど、結局 Free ってなんなのなんであんな定義なの天下り的に Functor に対する fixed point operator が出てきたと思ったら Done 書きたくないとかいう理由で値コンストラクタ増えて気がついたら Monadインスタンスになってたけど結局どういうことなの、みたいな…そういう気持ちに…なるのではないかと…ボクがはじめて読んだ時は最初そうなった、みたいな…

使い方とかそういうのは検索すればいくらでも出てくるわけで、そんなのボクの拙い日本語で説明しなくてもいい。

というわけで、Free という構造を分かりやすく説明できないものか、と思って発表してみました。Monad がどうみたいなのは放っておく。純粋に Free という構造にフォーカスする。とはいえ、いきなり Free から攻めるのは得策ではない。どうしたものかなあ…

 

というような具合で、色々考えた結果出来上がったのが今回の発表スライドです。List や Tree という卑近な例から、データ構造の共通部分を取り出して、まずは ListLike として一般化する。ListLike から IntList や IntTree が作れることを示す。そこに RoseTree をぶつけて強引に non-parametric なμ-operator の話に持っていく。その後、当然発表タイトルどおりに(詐欺タイトルですが)genericity のために parametric な定義に持ち込む。あとは出来上がった parametric な μ-operator に対して、足したり引いたりしていると Free が導出できるぞ、と持っていく。

要するに、μ-operator も Free も ADT が F-始代数となることが基盤にあるので、List や Tree という卑近な例から順を追って Free まで繋げたといってもいい。勿論 why free monads matter でも Free で List が表現可能なのは取り上げられているんですが、あっちはそこまで踏み込んでないしアプローチが逆。

 

実際に発表してみると、variance って何ですかみたいな説明とか fixed-point とは~みたいな話とか、この reduce どうやって再帰してるんですかとか色々あって、発表時間をほとんど一人で使ってしまいました(すいません…)。なかなか難しいものだなあと思いました。論文しか読んでないのでその辺の感覚がずれてしまっている。Nothing について突っ込まれなかったのは、今考えると運がよかった。分からなかった人いたら申し訳ない…あれを説明するのも大変だしなあ。全部多相的な値を素直に扱えない scala が悪い。covariant と、全てのクラスのサブタイプとして扱われる Nothing を使うと、多相的な値のように振舞う値を作れるよ、という話なのですが、これもよくよく考えると、知らない人がいてもおかしくなかった。参加者層はある程度常連もいるとはいえ、初心者の方も多いのだから。一般的なプログラマの感覚を取り戻さないとまずい感じがする。

reduce については面倒くさいので rpscala の gitter から引用。

tsukaby: 個人的にはmapとreduceの部分の再帰が停止する部分が難しかったです

lyricallogical: あれはようは type Proc = () => Unit; def f(g: Proc => Unit): Unit = g*1 みたいな感じですね

tsukaby: ふむふむ g,f,g,f,g,...って再帰するけど最終的にはgは何も実行しないから止まるっていうことですよね ちょっともっかいコード見てきます

lyricallogical: そうですね、自分自身を呼び出す無名関数を高階関数に渡すんだけれど、その無名関数が呼ばれるかどうかは自由なので、呼び出して再帰させてもいいし、呼び出さず停止させてもいいみたいな感じですね

tsukaby: ああー、ちょっとわかってきたかも。最終的には終端であるIntNilFに到達して、この場合fが実行されないから止まるってことですか?

lyricallogical: そうですね。

 そんな感じです。

 

資料作ってる最中は、我ながら悪くない方向から攻められたのでは、と思ったのですが、終わってみると勇み足だったなあという感じです。難しいですね。最後狙ったとはいえ駆け足過ぎるし。

 

人に物を教えるというのは難しい。精進します。おしまい。お薬の副作用で変な時間に寝まくってるので眠れないのです…生活リズム完全に崩壊してる…

*1:) => f(g