Sorulması gereken en iyi şeyin, onu nasıl arayacağımız değil, böyle bir kod parçasını nasıl analiz edeceğimiz olduğunu söyleyebilirim . Ve böyle bir analizde ilk kilit sorum şu olurdu:
- Yan etki, fonksiyonun argümanına mı, yoksa yan etkinin sonucuna mı bağlı?
- Hayır: "Etkili işlev", saf bir işleve, etkili bir eylem ve bunları birleştirmek için bir mekanizmaya yeniden yansıtılabilir.
- Evet: "Etkin işlev", monadik bir sonuç veren bir işlevdir.
Bu Haskell'de açıklamak kolaydır (ve bu cümle sadece şakanın yarısıdır). "Hayır" davasına bir örnek şöyle olur:
double :: Num a => a -> IO a
double x = do
putStrLn "I'm doubling some number"
return (x*2)
Bu örnekte yaptığımız eylemin (satırı basmak "I'm doubling some number") xsonuç ve sonuç arasındaki ilişki üzerinde hiçbir etkisi yoktur . Bu , fonksiyonun ve etkinin aslında ortogonal olduğunu gösteren, bu şekilde yeniden sınıflandırma yapabileceğimiz anlamına gelir ( Applicativesınıfı ve *>işlecini kullanarak ):
double :: Num a => a -> IO a
double x = action *> pure (function x)
where
-- The pure function
function x = x*2
-- The side effect
action = putStrLn "I'm doubling some number"
Yani bu durumda ben şahsen, bunun saf bir işlevi hesaba katabileceğiniz bir durum olduğunu söyleyebilirim. Birçok Haskell programlaması bununla ilgilidir - saf parçaların etkili koddan nasıl çıkarılacağını öğrenmek.
Saf ve etkili parçaların ortogonal olmadığı "evet" sınıfına bir örnek:
double :: Num a => a -> IO a
double x = do
putStrLn ("I'm doubling the number " ++ show x)
return (x*2)
Şimdi, yazdırdığınız dize, değerine bağlıdır x. Fonksiyon parçası (çarpma xikişer) hala bunu faktör böylece Ancak, tüm yürürlükte bağlı değildir:
logged :: (a -> b) -> (a -> IO x) -> IO b
logged function logger a = do
logger a
return (function a)
double x = logged function logger
where function = (*2)
logger x putStrLn ("I'm doubling the number " ++ show x)
Başka örnekleri de söylemeye devam edebilirdim, ama umarım bu başladığım noktayı göstermek için yeterlidir: bir şeyi "çağırmazsınız", saf ve etkili parçaların ne kadar ilgili olduğunu analiz eder ve ne zaman çıkardıklarını analiz edersiniz. Avantajınız için.
Bu, Haskell'in Monadsınıfını bu kadar yaygın kullanmasının nedenlerinden biri . Monad'lar (diğer şeylerin yanı sıra) bu tür analizleri ve yeniden yapılanmaları yapmak için bir araçtır.