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"
) x
sonuç 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 ( Applicative
sı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 x
ikiş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 Monad
sı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.