Kafa karıştırıcı bir soru için kafa karıştırıcı bir başlık! A) monadları, b) IO monadını, c) Cont monad (Control.Monad.Cont) ve d) ContT devamı transformatör monadını anlıyorum. Ben tüm fonksiyonları Katkı monad (Cont r a
) olan bir program yazmak için nasıl anlamak ve ben bir program yazmak için anlamak - (Bu soruyu cevaplamak için yeterli olsa. Ve belli belirsiz genel anlamda monad transformatörleri anlamak) Burada tüm işlevleri birleştirilmiş Cont/IO monadında (ContT r IO a
) bulunur.Devam Monitörü içindeki IO monadından kaçış
Ama bazı fonksiyonları kombine Katkı/IO monad (ContT r IO a
) ve diğer fonksiyonları olan bir program yazmak nasıl merak ediyorum sadece Devam monad (Cont r a
) içindedir. Temel olarak, tüm programı devam tarzında yazmak istiyorum, ancak sadece IO monadını gerekli yerlerde kullanıyorum ("normal" Haskell kodunda olduğu gibi, sadece IO monadını gerekli olduğu yerde kullanıyorum). foo
IO gerekiyor ancak bar
saf
foo :: Int -> IO Int
foo n = do
let x = n + 1
print x
return $ bar x
bar :: Int -> Int
bar m = m * 2
Not olun: Örneğin
olmayan devamı tarzında bu iki işlevi, düşünün. Şimdi tamamen devamı monad kullanarak bu kod yazmak için nasıl düşündüm, ama ben de bar
aracılığıyla IO iplik için gerekli: 'Ben devamı tarzında tüm kodumu istiyorsun ama don
foo :: Int -> ContT r IO Int
foo n = do
let x = n + 1
liftIO $ print x
bar x
bar :: Int -> ContT r IO Int
bar m = return $ m * 2
t, IO monadını gerektirmeyen işlevler üzerinde kullanmak zorunda. Temelde, böyle bar
tanımlamak istiyorum:
bar :: Int -> Cont r Int
bar m = return $ m * 2
Ne yazık ki, bir ContT r IO a
monad fonksiyonu (foo
) içinden bir Cont r a
monad fonksiyonunu (bar
) aramak için bir yol bulmak mümkün değil. Dönüştürülmemiş bir monayı dönüştürülmüş olana "kaldırmak" için herhangi bir yol var mı? yani foo
'daki "bar x
" satırını bar :: Int -> Cont r Int
doğru şekilde arayabilmesi için nasıl değiştirebilirim? Control.Monad.Class devreye giriyor
Teşekkürler. Bu işe yarıyor. Ben de tam olarak istediğim şeyi ('Bar' değiştirmek zorunda değildim) verdi kendi çözümumu buldum: 'liftCont :: Cont (m r) a -> ContT r m a'; 'liftCont c = ContT $ runCont c'. Çözümüm 'Cont' un paketini açar ve' ContT' oluşturur. Çözümünüzün daha güzel olduğunu düşünüyorum çünkü bu polimorfiktir ve veri yapılarının gerçek manipülasyonunu gerektirmez, bu yüzden sizin için işaretleyin. Ama ben 'bar' değiştiremezseniz yararlıdır, çünkü benim başka bir yanıt olarak benim postalayacağım. Ayrıca "bar" da IO kullanmanın imkansız olduğunu açıklamak için +1. – mgiuca