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についての解説を書きたいと思います。