Arrowパズル
このまえ書いたArrowLoopで階乗を計算するサンプルが全然Arrowらしくなかったので、ArrowらしいArrowLoopのサンプルを書いてみます。
初級編
??? = loop (snd &&& uncurry(:)) ??? = loop (snd &&& uncurry(++)) ??? = loop $ snd >>> id&&&(id&&&tail >>> uncurry (zipWith (+)) >>> (1:) >>> (1:))
上の2つはよく使うある関数をArrowで書いたもの
最後の1つは有名なある数列をArrowで書いたものです。
中級編
cond f = \x -> if f x then Left x else Right x ??? = loop $ (snd&&&fst>>>app)&&&((<<<(cond(== 0)))<<<(const 1|||) <<<(uncurry(*)<<<)<<<(id&&&)<<<(<<<(subtract 1))<<<snd)
ArrowではLeftかRightかで分岐をするので補助関数condを用意しました。入力にfを適用した結果がTrueならLeft、FalseならRightを付けて出力します。
このコードは何をしているでしょうか。
上級編
??? :: Ord a => [a] -> [a] ??? = loop $ (snd&&&fst>>>app)&&&((<<<(cond null))<<<(const []|||) <<<(uncurry(++)<<<)<<<(second(uncurry(:))<<<)<<<(uncurry(&&&)) <<<(<<<app<<<(filter<<<(>)<<<head)&&&tail) &&&((head&&&)<<<(<<<app<<<(filter<<<(<=)<<<head)&&&tail))<<<snd)
この変態コードが何をしているかわかるでしょうか。
(注):以上はArrowの間違った使用方法です。
現在説明の為の絵などを描いているところです。明日ArrowLoopについての解説を書きたいと思います。