Hızlı ref:
evaluate
türüdür:
evaluate :: a -> IO a
seq
tip a -> b -> b
sahiptir. İlk önce ilk argümanı değerlendirir, ardından ikinci argümanı döndürür. return $! x
ve (return $! x) >>= return
arasındaki fark şu ifadeyle belirginleşir
evaluate x `seq` y ==> y
evaluate x `catch` f ==> (return $! x) `catch` f
evaluate x >>= f ==> (return $! x) >>= f
:
evaluate undefined `seq` 42
ilk kural olarak, bu 42'ye değerlendirmek gerekir
değerlendirin
bu üç kurallara uyar
iletanımında, yukarıdaki ifade tanımlanmamış bir istisna neden olur. Bu IO değeri hesaplanır zaman 42.
Temel olarak, return $! x
bir şekilde sıkı eşit yapar (return $! x) >>= return
tanımı ile eşit 42.
değil değeri ⊥ sahiptir. Diğer form sadece IO değeri çalıştırıldığında ve kullanılan değer (>>=
kullanarak) katıdır. Daha fazla ayrıntı için bkz. this mailing list thread.
Bu aslında monad yasalarını ihlal etmiyor mu? – leftaroundabout
@leftaroundabout Hayır, öyle değil. Her ikisi de eğer koşarsa tam olarak aynı şekilde davranır, ama ifadeleri “seçerseniz,” geri dönüşü verir! x' bir 'seq' dışına sahiptir, '(return $! x) >> = return' bir' (>> =) 'dışa doğrudur. –
@leftaroundabout: Hayır, çünkü yasalar bakımından ⊥ dikkate alınmaz. Reader gibi standart monadlar da aynı şekilde davranır. (Daniel Fischer'ın argümanını (diğerlerinden daha önce duyduğum) satın almıyorum, çünkü "eğer koşarsa tam olarak aynı davranın" gerçekten iyi tanımlanmış bir kavram değildir.) – ehird