まず、素敵な定義があります
x = 1 : map (2*) x
これまでに見たことがない場合、それ自体が少し気が遠くなるようなものです。とにかく、これは怠惰と再帰のかなり標準的なトリックです。fix
ここで、 と point-free-ifyを使用して明示的な再帰を取り除きます。
x = fix (\vs -> 1 : map (2*) vs)
x = fix ((1:) . map (2*))
次に行うことは、:
セクションを拡張して、map
不必要に複雑にすることです。
x = fix ((:) 1 . (map . (*) . (*2)) 1)
これで、その定数の 2 つのコピーができました1
。これではうまくいかないので、reader applicative を使用して重複を排除します。あと、関数合成がちょっとゴミっぽいので、そこそこ置き換えてみましょう(<$>)
。
x = fix (liftA2 (.) (:) (map . (*) . (*2)) 1)
x = fix (((.) <$> (:) <*> (map . (*) . (*2))) 1)
x = fix (((<$>) <$> (:) <*> (map <$> (*) <$> (*2))) 1)
次は、 への呼び出しmap
があまりにも読みにくいです。しかし、恐れることは何もありません: モナド法則を使って少し拡張することができます。特に 、fmap f x = x >>= return . f
だから
map f x = x >>= return . f
map f x = ((:[]) <$> f) =<< x
ポイントフリー化して、 に置き換え(.)
て(<$>)
から、スプリアス セクションを追加できます。
map = (=<<) . ((:[]) <$>)
map = (=<<) <$> ((:[]) <$>)
map = (<$> ((:[]) <$>)) (=<<)
前のステップでこの方程式を代入します。
x = fix (((<$>) <$> (:) <*> ((<$> ((:[]) <$>)) (=<<) <$> (*) <$> (*2))) 1)
最後に、スペースバーを壊して、素晴らしい最終方程式を作成します
x=fix(((<$>)<$>(:)<*>((<$>((:[])<$>))(=<<)<$>(*)<$>(*2)))1)