Bu, IO
türünde negatif bir konum nedeniyle tüm MonadIO
örneklerinde genel olarak yapılamaz. Belirli durumlar için bunu yapan bazı kütüphaneler vardır (monad-control,), ancak özellikle istisnalar ve benzer garip IO
y şeyleri nasıl ele aldıklarına dair, anlamsal olarak sağlam olup olmadıklarına dair bazı tartışmalar olmuştur.
Düzenleme: Bazı kullanıcılar pozitif/negatif konum ayrımıyla ilgilenir. Aslında söyleyecek fazla bir şey yok (muhtemelen çoktan duymuşsunuzdur ama farklı bir adla). Terminoloji alt tür dünyasından gelir.
alttiplendirmesinde arkasında sezgi
"
a
bir
a
bir
b
yerine bekleniyordu yerde kullanılabilen
b
bir alt tipi (I
a <= b
yazacağım ki) 'dir" olmasıdır. Alt türlemeye karar vermek birçok durumda basittir; Ürünler için,
a1 <= b1
ve
a2 <= b2
gibi, her zaman çok basit bir kural olan
(a1, a2) <= (b1, b2)
. Fakat birkaç zor durum var; örneğin, ne zaman
a1 -> a2 <= b1 -> b2
karar vermeliyiz?
f :: a1 -> a2
numaralı bir işleve ve b1 -> b2
türünde bir işlev beklediğimiz bir bağlama sahibiz. Bu nedenle, b2
gibi, f
dönüş değeri kullanacak, dolayısıyla a2 <= b2
. Zor olan şey, f
'un a1
olduğu gibi kullanması bile bağlamın f
'u b1
ile sağlamasıdır. Bu nedenle, b1 <= a1
- bunu tahmin edebildiğinizden geriye doğru bakmalıyız! a2
ve b2
'un "kovaryant" olduğunu veya "pozitif bir pozisyonda" olduğunu ve a1
ve b1
"kontravaryant" olduğunu veya bir "negatif pozisyonda" meydana geldiğini söylüyoruz.
(Hızlı kenara:? "Olumlu" ve "olumsuz" Bu çarpma motive neden bu iki tür düşünün:.? I
f1 :: ((a1 -> b1) -> c1) -> (d1 -> e1)
f2 :: ((a2 -> b2) -> c2) -> (d2 -> e2)
zaman
f1
ler türü 'ın tipi
f2
bir alt türü olması' gerektiğini Bu gerçekleri devlet (egzersiz: yukarıdaki kuralı kullanılarak bu kontrol edin):
- Biz
e1 <= e2
olmalıdır
- Biz
d2 <= d1
olmalıdır ..
c2 <= c1
olmalıdır.
b1 <= b2
olmalıdır.
a2 <= a1
olmalıdır.
e1
f1
tipinde pozitif bir pozisyonda da olduğu d1 -> e1
pozitif pozisyonda olduğu; dahası, e1
, f1
türünde pozitif bir konumdadır (yukarıdaki gerçeğe göre kovaryant olduğundan). Tüm dönem içindeki konumu, her bir alt pozisyondaki pozisyonunun ürünüdür: pozitif * pozitif = pozitif. Benzer şekilde, d1
tüm tipte pozitif bir konumda olan d1 -> e1
'da negatif bir konumdadır. Negatif * pozitif = negatif ve d
değişkenleri gerçekten dezavantajlıdır. b1
, a1 -> b1
türünde, (a1 -> b1) -> c1
negatif bir konumda olan pozitif bir konumdadır; bu, tümüyle negatif bir konumdadır. Pozitif * Negatif * Negatif = Pozitif ve Kovaryantı. Sen fikir edinmek)
Şimdi, MonadIO
sınıfa bir göz atalım:.
class Monad m => MonadIO m where
liftIO :: IO a -> m a
Biz alttiplendirmesinde açık bir beyanı olarak görebilirsiniz: Biz IO a
bir alt tip olmak için bir yol veriyoruz Bazı beton m
için m a
. Hemen biliyoruz ki IO
yapıcıları ile pozitif pozisyonlarda herhangi bir değer alabilir ve m
s. Ama hepsi bu: IO
negatif kurucuları m
s'ye dönüştürmenin hiçbir yolu yok - bunun için daha ilginç bir sınıfa ihtiyacımız var.
Gah! Bütün Haskell neden bu kadar zor? Burada hiçbir kolay nokta yok :-( – drozzy
@drozzy: Bu etiket aslında [cevap başına en yüksek ortalama upvotes'tan birine sahiptir] (http://data.stackexchange.com/stackoverflow/query/61353/tags-with-highest-average -answer-skorlar-en-1000-sorular-etiketler arasında, bu yüzden onlar her zaman kolay olmasa da, insanlar çabaları için ödüllendirilirler. – hammar