Để bắt đầu, chúng ta có định nghĩa đáng yêu
x = 1 : map (2*) x
bản thân nó có một chút suy nghĩ nếu bạn chưa từng thấy nó trước đây. Dù sao thì đó cũng là một mẹo khá tiêu chuẩn của sự lười biếng và đệ quy. Bây giờ, chúng ta sẽ loại bỏ đệ quy rõ ràng bằng cách sử dụng fix
và point-free-ify.
x = fix (\vs -> 1 : map (2*) vs)
x = fix ((1:) . map (2*))
Điều tiếp theo chúng tôi sẽ làm là mở rộng :
phần và làm cho phần map
phức tạp không cần thiết.
x = fix ((:) 1 . (map . (*) . (*2)) 1)
Bây giờ chúng ta có hai bản sao của hằng số đó 1
. Điều đó sẽ không bao giờ xảy ra, vì vậy chúng tôi sẽ sử dụng ứng dụng người đọc để loại bỏ trùng lặp. Ngoài ra, thành phần chức năng là một chút rác, vì vậy hãy thay thế nó bằng (<$>)
bất cứ nơi nào chúng ta có thể.
x = fix (liftA2 (.) (:) (map . (*) . (*2)) 1)
x = fix (((.) <$> (:) <*> (map . (*) . (*2))) 1)
x = fix (((<$>) <$> (:) <*> (map <$> (*) <$> (*2))) 1)
Tiếp theo: cuộc gọi đến đó map
quá khó đọc. Nhưng không có gì phải lo sợ: chúng ta có thể sử dụng luật đơn nguyên để mở rộng nó một chút. Đặc biệt fmap f x = x >>= return . f
, vì vậy
map f x = x >>= return . f
map f x = ((:[]) <$> f) =<< x
Chúng tôi có thể point-free-ify, thay thế (.)
bằng (<$>)
và sau đó thêm một số phần giả mạo:
map = (=<<) . ((:[]) <$>)
map = (=<<) <$> ((:[]) <$>)
map = (<$> ((:[]) <$>)) (=<<)
Thay thế phương trình này trong bước trước của chúng tôi:
x = fix (((<$>) <$> (:) <*> ((<$> ((:[]) <$>)) (=<<) <$> (*) <$> (*2))) 1)
Cuối cùng, bạn phá vỡ phím cách và tạo ra phương trình cuối cùng tuyệt vời
x=fix(((<$>)<$>(:)<*>((<$>((:[])<$>))(=<<)<$>(*)<$>(*2)))1)