Başlangıç olarak, güzel tanımımız var
x = 1 : map (2*) x
eğer daha önce hiç görmediyseniz, kendi başına biraz kafa karıştırıcıdır. Her neyse, bu oldukça standart bir tembellik ve özyineleme numarasıdır. Şimdi, fix
ve point-free-ify kullanarak açık özyinelemeden kurtulacağız .
x = fix (\vs -> 1 : map (2*) vs)
x = fix ((1:) . map (2*))
Sonraki yapacağımız şey :
bölümü genişletmek ve map
gereksiz yere karmaşık hale getirmek .
x = fix ((:) 1 . (map . (*) . (*2)) 1)
Şimdi bu sabitin iki kopyasına sahibiz 1
. Bu asla işe yaramayacak, bu yüzden bunu kopyalamak için okuyucu uygulamalarını kullanacağız. Ayrıca, işlev bileşimi biraz saçmadır, bu yüzden (<$>)
onu elimizden geldiğince değiştirelim .
x = fix (liftA2 (.) (:) (map . (*) . (*2)) 1)
x = fix (((.) <$> (:) <*> (map . (*) . (*2))) 1)
x = fix (((<$>) <$> (:) <*> (map <$> (*) <$> (*2))) 1)
Sıradaki: bu çağrı map
çok fazla okunabilir. Ancak korkulacak bir şey yok: Monad yasalarını biraz genişletmek için kullanabiliriz. Özellikle fmap f x = x >>= return . f
, bu yüzden
map f x = x >>= return . f
map f x = ((:[]) <$> f) =<< x
Biz, serbest-ify işaret yerine (.)
birlikte (<$>)
, ve sonra bazı sahte bölümler eklemek:
map = (=<<) . ((:[]) <$>)
map = (=<<) <$> ((:[]) <$>)
map = (<$> ((:[]) <$>)) (=<<)
Bu denklemi önceki adımımızda değiştirerek:
x = fix (((<$>) <$> (:) <*> ((<$> ((:[]) <$>)) (=<<) <$> (*) <$> (*2))) 1)
Sonunda, boşluk çubuğunuzu kırarsınız ve harika son denklemi oluşturursunuz
x=fix(((<$>)<$>(:)<*>((<$>((:[])<$>))(=<<)<$>(*)<$>(*2)))1)