Bu, IO
monad'ın önerilen bir "yorumu" dur. Bu "yorumu" ciddiye almak istiyorsanız, "RealWorld" ü ciddiye almanız gerekir. Olup olmadığı alakasız action world
spekülatif değerlendirildi alır ya da olmasın, action
herhangi bir yan etkiye sahip olmayan, etkileri, eğer varsa, bu etkiler, örneğin, bir ağ paket olmuştur Gönderilen meydana gelmiş evrenin yeni durumunu iade tarafından işlenir. Bununla birlikte, fonksiyonun sonucu ((),world)
ve bu nedenle evrenin yeni halidir world
. Spekülatif olarak değerlendirdiğimiz yeni evreni kullanmıyoruz. Evrenin durumu world
.
Muhtemelen bunu ciddiye almakta zorlanıyorsunuz. Bunun en iyi yüzeysel olarak paradoksal ve saçmalık olmasının birçok yolu vardır. Eşzamanlılık, bu bakış açısıyla özellikle açık ya da çılgındır.
"Bekle, bekle," diyorsun. " RealWorld
sadece bir 'jeton'dur. Aslında tüm evrenin durumu değildir ." Tamam, o zaman bu "yorum" hiçbir şeyi açıklamaz. Bununla birlikte, bir uygulama detayı olarak , GHC modelleri bu şekilde IO
. 1 Ancak bu, aslında yan etkileri olan büyülü "işlevlere" sahip olduğumuz anlamına gelir ve bu model anlamlarına rehberlik etmez. Ve bu işlevler aslında yan etkilere sahip olduğundan, dile getirdiğiniz endişe tamamen önemlidir. GHC gelmez emin olmak için kendi yolumdan gitmek zorunda RealWorld
ve bu özel fonksiyonlar programın amaçlanan davranışını değiştirmek şekillerde optimize edilmemiştir.
Şahsen (muhtemelen şimdiye kadar açıkça görüldüğü gibi), bu "dünyadan geçen" modelin IO
pedagojik bir araç olarak işe yaramaz ve kafa karıştırıcı olduğunu düşünüyorum . (Uygulama için yararlı olsun, bilmiyorum. GHC için, daha çok tarihsel bir eser olduğunu düşünüyorum.)
Alternatif bir yaklaşım, IO
yanıt işleyicileri ile istekleri açıklayan bir görünüm olarak görmek . Bunu yapmanın çeşitli yolları var. Muhtemelen en erişilebilir, ücretsiz bir monad yapısı kullanmaktır, özellikle şunları kullanabiliriz:
data IO a = Return a | Request OSRequest (OSResponse -> IO a)
Bunu daha sofistike hale getirmenin ve biraz daha iyi özelliklere sahip olmanın birçok yolu var, ancak bu zaten bir gelişme. Anlamak için gerçekliğin doğası hakkında derin felsefi varsayımlar gerektirmez. Tek söylediği IO
, ya bir Return
değer döndürmekten başka bir şey yapmayan önemsiz bir program ya da yanıt için bir işleyici ile işletim sistemine bir istek olmasıdır. OSRequest
gibi bir şey olabilir:
data OSRequest = OpenFile FilePath | PutStr String | ...
Benzer şekilde, OSResponse
şöyle bir şey olabilir:
data OSResponse = Errno Int | OpenSucceeded Handle | ...
(Yapılabilecek iyileştirmelerden biri, OpenSucceeded
bir PutStr
istekten yararlanamayacağınızı bilmeniz için işleri daha güvenli hale getirmektir .) Bu modeller IO
, bazı sistem tarafından yorumlanan istekleri ("gerçek" IO
monad için Haskell çalışma zamanının kendisi) ve belki de bu sistem yanıt verdiğimiz işleyiciyi arayacaktır. Bu, elbette, benzer bir talebin nasıl PutStr "hello world"
ele alınması gerektiğine dair herhangi bir belirti vermez, ancak aynı şekilde davranmaz. Bunun başka bir sisteme devredildiğini açıkça ortaya koymaktadır. Bu model de oldukça doğru. Modern işletim sistemlerindeki tüm kullanıcı programları, herhangi bir şey yapmak için işletim sisteminden talepte bulunmalıdır.
Bu model doğru sezgileri sağlar. Örneğin, pek çok yeni başlayan kişi <-
operatör gibi şeyleri "paketten çıkarma" olarak görür IO
ya da (maalesef güçlendirilmiş) görüşe sahip olan IO String
ve diyelim ki "içeren" bir konteynerdir String
(ve sonra <-
bunları çıkarır). Bu istek-yanıt görünümü bu perspektifi açıkça yanlış yapar. İçinde dosya tanıtıcısı yok OpenFile "foo" (\r -> ...)
. Bunu vurgulamak için yaygın bir benzetme, kek tarifinin içinde kek olmamasıdır (veya bu durumda "fatura" daha iyi olabilir).
Bu model aynı zamanda eşzamanlılık ile kolayca çalışır. Biz kolayca için bir kurucu olabilir OSRequest
gibi Fork :: (OSResponse -> IO ()) -> OSRequest
ve daha sonra çalışma zamanı o seviyor ancak normal bir işleyicisi ile bu ekstra işleyicisi tarafından üretilen istekleri serpiştirebilir. Biraz zekâ ile bunu (ya da ilgili teknikleri) eşzamanlılık gibi şeyleri sadece "işletim sistemine bir talepte bulunuruz ve işler olur" demek yerine daha doğrudan modellemek için kullanabilirsiniz. Bu nasıl IOSpec
kütüphane çalışır.
1 Sarılmalar IO
, açık bir veri türü yerine opak işlevlerle de olsa, tanımladığım şeye benzeyen, devam tabanlı bir uygulama kullandı . HBC ayrıca eski istek-yanıt akışı tabanlı ES üzerinde katmanlı bir uygulama tabanlı uygulama kullanmıştır. NHC (ve dolayısıyla YHC) thunks kullandı, yani kabaca çağrılmış IO a = () -> a
olsa da ()
, World
durum geçişi yapmıyor. JHC ve UHC temel olarak GHC ile aynı yaklaşımı kullandı.