Na początek mamy cudowną definicję
x = 1 : map (2*) x
co samo w sobie jest nieco zagmatwane, jeśli nigdy wcześniej go nie widziałeś. W każdym razie jest to dość standardowa sztuczka lenistwa i rekurencji. Teraz pozbędziemy się jawnej rekurencji przy użyciu fix
i ify bez punktów.
x = fix (\vs -> 1 : map (2*) vs)
x = fix ((1:) . map (2*))
Następną rzeczą, którą zamierzamy zrobić, jest rozszerzenie :
sekcji i map
niepotrzebnie skomplikowane.
x = fix ((:) 1 . (map . (*) . (*2)) 1)
Cóż, teraz mamy dwie kopie tej stałej 1
. To nigdy się nie uda, więc użyjemy aplikacji czytnika, aby to zduplikować. Również kompozycja funkcji to trochę bzdura, więc zastąpmy to (<$>)
gdziekolwiek się da.
x = fix (liftA2 (.) (:) (map . (*) . (*2)) 1)
x = fix (((.) <$> (:) <*> (map . (*) . (*2))) 1)
x = fix (((<$>) <$> (:) <*> (map <$> (*) <$> (*2))) 1)
Dalej: to wezwanie map
jest zbyt czytelne. Ale nie ma się czego bać: możemy wykorzystać prawa monady, aby ją nieco rozszerzyć. W szczególności fmap f x = x >>= return . f
tzw
map f x = x >>= return . f
map f x = ((:[]) <$> f) =<< x
Możemy wskazać-free-IFY wymienić (.)
z (<$>)
, a następnie dodać kilka odcinków fałszywe:
map = (=<<) . ((:[]) <$>)
map = (=<<) <$> ((:[]) <$>)
map = (<$> ((:[]) <$>)) (=<<)
Zastępując to równanie w naszym poprzednim kroku:
x = fix (((<$>) <$> (:) <*> ((<$> ((:[]) <$>)) (=<<) <$> (*) <$> (*2))) 1)
Na koniec łamiesz spację i tworzysz wspaniałe końcowe równanie
x=fix(((<$>)<$>(:)<*>((<$>((:[])<$>))(=<<)<$>(*)<$>(*2)))1)