2016-01-09 8 views
14

:Thrash çöp toplandığında Haskell bir kıvılcım atıyor mu? Örneğin

x :: Maybe a 
y :: a 
y `par` x `pseq` (fromMaybe y x) 

y kıvılcımı durdu ve x eğer atılır (çok) hesaplanır er ve Just ... mı?

Daha spesifik olmak gerekirse, bir listeyi aramak istiyorum, ancak her karşılaştırma oldukça maliyetlidir. Aramayı paralel hale getirmek istiyorum, ancak bir eşleşme bulunduğunda geri kalanların atılmasını istiyorum.

cevap

4

Bunu mu demek istediniz: fromMaybe yerine maybe?

x `par` y `pseq` (fromMaybe y x) 

Ayrıca x değil y değerlendirmek için bir kıvılcım yaratıyor. Dolayısıyla fromMaybe y x, y değerlendirilinceye kadar değerlendirilmeyecektir.

y `par` x `pseq` (fromMaybe y x) 

üzerindeki tüm doğruysa, o zaman sorunun cevabı zaten başladı henüz başlamamış eğer atılacak olsa "hayır", kıvılcım (durdurulmaz ise: Muhtemelen tersini ima.) aşağıdaki testi ile kontrol edebilirsiniz:

import Data.Maybe 
import Control.Concurrent 
import Control.Parallel 
import System.IO.Unsafe 
import System.Mem 

{-# NOINLINE x #-} 
x = unsafePerformIO $ do 
    threadDelay 1000 
    return (Just 1) 

{-# NOINLINE y #-} 
y = unsafePerformIO $ do 
    print "will eval y" 
    threadDelay 3000000 
    print "did eval y" 
    return (2 :: Int) 

main :: IO() 
main = do 
    print $ y `par` x `pseq` fromMaybe y x 
    print "done" 
    performGC 
    threadDelay 4000000 

çıktı:

"will eval y" 
1 
"done" 
"did eval y" 

Ayrıca, +RTS -s çalışma zamanı istatistikleri kontrol edebilirsiniz. Bir dizi GC'd kıvılcım içerir.

+0

Evet, hatalarımın olduğu gibi düzeltmiş oldunuz :), teşekkürler! Bu yüzden görevleri sonlandırmak için eşzamanlılık kullanmak ve 'killThread' ile dişleri elle öldürmek zorunda kalmam gerektiğine inanıyorum. –