liftM2 combinator bir 'daha işlevsel' bir şekilde bunu yapmanın Okuyucu monad kullanılabilir: ithalat önemli olduğunu
import Control.Monad
import Control.Monad.Reader
-- ....
filter (liftM2 (&&) odd (> 100)) [1..200]
Not; Control.Monad.Reader, tüm bunların çalışmasını sağlayan Monad (e ->) örneğini sağlar.
Bu çalışmanın nedeni, okuyucu monadının bazı ortamlar için (e ->) olmasıdır. Dolayısıyla, bir boole yüklemi, argümanına karşılık gelen bir ortamda bool döndüren 0-ary monadik bir fonksiyondur. Daha sonra, bu tür iki yüklemeden dolayı ortamı dağıtmak için liftM2'yi kullanabiliriz.
Ya türleri dışarı çalışırken, daha basit açısından, liftM2 böyle biraz hareket edecek:
liftM2 f g h a = f (g a) (h a)
Ayrıca bunlar kolayca zinciri edebilmek istiyorsanız yeni bir bağdaştırıcının tanımlayabilir ve/ya liftM2 bulaşmak istemiyorum:
(.&&.) :: (a -> Bool) -> (a -> Bool) -> (a -> Bool)
(.&&.) f g a = (f a) && (g a)
-- or, in points-free style:
(.&&.) = liftM2 (&&)
filter (odd .&&. (> 5) .&&. (< 20)) [1..100]
Her iki örnek ghc 7.6.3 üzerinde çalışmak size 'Control.Monad.Reader' içe olmasa bile. – sjakobi
Ben liftM2' şu şekilde değiştirilmiş olabilir: 'filtre ((&&) <$> tek <*> (> 100)) [1.200]'. Aynı, ama daha güzel. :) Ayrıca sadece "Control.Applicative" ve tam monadlar gerektirmez. … Operatörün iki Boolean işlevinden çok ANDing'e izin vermesini hala merak etmeme rağmen… – Evi1M4chine