今更PHPでモナド的なものを書く
http://blog.dakatsuka.jp/2013/09/03/php-maybe-monad.html
この辺とか
http://d.hatena.ne.jp/kazu-yamamoto/20110413/1302683869
この辺とか見てたらちょっとやってみたくなったので。
○○言語でMonad実装って結構あるけど、MonadPlus使えないとあまり意味ないよね?的なところもある。
上記URLのTree探索するやつの
msearch :: MonadPlus m => (Int -> Bool) -> Tree -> m Int
これ、型推論、テンプレート、ジェネリクス、戻り値の型がないPHPでは無理目なので、コンテキスト(MonadPlus m)を引数として渡すことにする。
traitがあればreturnやmzeroを共通化できるので多少マシじゃないかな?と思いつつ。
<?php private function searchTree(Context $m, callable $f, Tree $tree) { if ($tree instanceof EmptyTree) return $m->mzero(); if ($f($tree->value)) return $this->searchTree($m, $f, $tree->left) ->mplus($m->ret($tree->value)) ->mplus($this->searchTree($m, $f, $tree->right)); else return $this->searchTree($m, $f, $tree->left) ->mplus($this->searchTree($m, $f, $tree->right)); } private function getTree() { $empty = new EmptyTree(); return new Tree(3, new Tree(2, $empty, $empty), new Tree(1, $empty, $empty)); } public function testTreeDataList() { $c = new DataListContext(); $f = function($a){ return $a % 2 == 1; }; $t = $this->getTree(); $ret = $this->searchTree($c, $f, $t); $this->assertEquals(Cons::fromArray([3,1]), $ret); } public function testTreeMaybe() { $c = new MaybeContext(); $f = function($a){ return $a % 2 == 1; }; $t = $this->getTree(); $ret = $this->searchTree($c, $f, $t); $this->assertEquals(new Just(3), $ret); }https://github.com/nishimura/laiz-monad/blob/master/test/src/Laiz/Test/Monad/ContextTest.php
タイプ量が多い…。
traitってこういう使い方で良かったんだっけ?ファイルの置き場所とかセオリーが分からん。
composer.json置いてるけど未登録。