bu konuda unsafeInterleaveIO
veya herhangi tembel IO kullanmayın. Bu, yinelemelerin, tahmin edilemeyen kaynak yönetimini sağlayan tembel IO'dan kaçınmak için oluşturulduğu problemdir. Hile asla listesini oluşturmak ve bunu kullanarak bitene kadar yineleme kullanarak sürekli akışı. Bunu göstermek için kendi kütüphanemden, pipes
'dan örnekler kullanacağım.
Öncelikle tanımlayın:
import Control.Monad
import Control.Monad.Trans
import Control.Pipe
-- Demand only 'n' elements
take' :: (Monad m) => Int -> Pipe a a m()
take' n = replicateM_ n $ do
a <- await
yield a
-- Print all incoming elements
printer :: (Show a) => Consumer a IO r
printer = forever $ do
a <- await
lift $ print a
Şimdi bizim kullanıcıya ortalama olalım ve onlar bizim için gerçekten büyük liste üretmek talep: Artık
prompt100 :: Producer Int IO()
prompt100 = replicateM_ 1000 $ do
lift $ putStrLn "Enter an integer: "
n <- lift readLn
yield n
, hadi çalışmasına izin:
>>> runPipe $ printer <+< take' 1 <+< prompt100
Enter an integer:
3<Enter>
3
Sadece bir tam sayı ister, çünkü yalnızca bir tam sayı isteriz!
yourProducer :: Producer b IO()
yourProducer = do
xs <- lift getLargeList
mapM_ yield xs
... sonra çalıştırın: Eğer getLargeList
dan çıkışı ile prompt100
değiştirmek istiyorsanız
, sadece yazma
>>> runPipe $ printer <+< take' 1 <+< yourProducer
Bu lazily inşa listesini akışı ve asla güvenli olmayan tüm IO
hacks kullanmadan, bellekte liste. Sadece böyle fazla örnek için take'
geçmek değerini değiştirmek, sen talep kaç unsurlar değiştirmek için Control.Pipe.Tutorial
de pipes
tutorial okuyun.
tembel IO sorunlara neden niçin hakkında daha fazla bilgi için,
here bulabilirsiniz konuyla ilgili Oleg'in orijinal slaytlar okuyun.Tembel IO kullanarak sorunları açıklamak için harika bir iş çıkarır. Tembel IO kullanmaya zorlandığınız her zaman, gerçekten istediğiniz şey yinelenen bir kütüphanedir.
Belki bu yardımcı olacaktır. http://stackoverflow.com/questions/3270255/is-haskells-mapm-not-lazy –
Anton, Bu konuyu okudum, ama cevabı bulamadım: tembel hesaplamalar için mapM bir alternatif var. –
@DmitryBespalov Aynı tür imzayla değil. Monad'ın daha sonraya kadar etkileri ertelemek için bir soyutlaması yoktur - bu da 'mapM'nin daha tembel olması için yapmanız gereken şey. – Carl