Başka yolları da devlet Monadlar ile yanında saf fonksiyonel bir dil ne olabilir?
Monadlar (Haskell kullanılan) alışmaya başladım. Başka yollar IO veya devlet saf fonksiyonel bir dil (hem teori ya da realite) olarak ele alınabilir ne merak ediyorum. Örneğin, mantıksal bir dil denir "cıva" kullanan "etki-yazma". Haskell gibi bir program, nasıl etkisi-yazarak çalışmak istiyorsunuz? Nasıl Diğer sistemler çalışıyor mu?
CEVAP
Birkaç farklı sorular var.
İlk, IO
State
çok farklı şeylerdir. State
yapmak kolay
kendinizi her fonksiyonu için ekstra bir argüman, ve ekstra bir dönüş
sonucu, ve"; örneğin, turn a -> b
içine fonksiyon "duruma bir
a -> s -> (b,s)
.
Büyü var no: Control.Monad.State
bir sarıcı sağlar
"devlet eylemleri" şeklinde s -> (a,s)
uygun olarak çalışma yapar
yardımcı işlevler, ama bir grup olarak.
O, doğası gereği uygulanmasında bazı büyü var. Ama var kelime içermeyen Haskell G/Ç ifade etmenin pek çok yolu"". monad IO-ücretsiz olarak-Haskell alt ettik, ve IO icat etmek isteseydik çizik, monadlar hakkında hiçbir şey bilmeden, biz belki çok şey var yapın.
Eğer yapmak istediğimiz tüm stdout baskı, örneğin, söyleyebiliriz:
type PrintOnlyIO = String
main :: PrintOnlyIO
main = "Hello world!"
Ve sonra Dize değerlendirir ve yazdıran bir RTS (çalışma sistemi). Bu bizi tamamen baskı meydana gelen herhangi bir Haskell program yazmak sağlar stdout.
Bu etkileşim istediğimiz için çok yararlı, ancak değil! Hadi icat yani bunu sağlayan IO yeni bir tür. Akla gelen en basit şey
type InteractIO = String -> String
main :: InteractIO
main = map toUpper
IO için bu yaklaşım bize standart girdiden okur, herhangi bir kod yazmanıza imkan ve yazar
(Başlangıç fonksiyonu interact :: InteractIO -> IO ()
ile birlikte gelir stdout
bu arada) yapar.
Bu bizi etkileşimli programlar yazmaya olanak sağladığı için çok daha iyi. Ama tek istediğimiz IO kıyasla hala çok sınırlı ve oldukça da hata eğilimli (eğer yanlışlıkla çok ileri stdın okumaya çalışın, program sadece kullanıcı türleri kadar fazla blok).
Daha fazla bilgi edinin daha stdin ve stdout yazmak istiyoruz. Nasıl burada Haskell erken sürümleri/I, yaklaşık:
data Request = PutStrLn String | GetLine | Exit | ...
data Response = Success | Str String | ...
type DialogueIO = [Response] -> [Request]
main :: DialogueIO
main resps1 =
PutStrLn "what's your name?"
: GetLine
: case resps1 of
Success : Str name : resps2 ->
PutStrLn ("hi " name "!")
: Exit
main
, yazıyoruz biz tembel bir liste değişkeni almak ve tembel bir listesini döndürür
sonuç. Biz dönüş tembel listesi PutStrLn s
GetLine
gibi değerler vardır;
biz (istek) bir değer verecek sonra bir sonraki eleman inceleyebiliriz
(yanıt) listesi ve RTS bizim cevap için ayarlayacaktır
istek.
Bu mekanizma daha iyi çalışma yapmak için yollar vardır, ama düşünün, bu yaklaşım çok garip çok hızlı bir şekilde alır. Ayrıca, hata eğilimli bir önceki ile aynı şekilde.
Burada çok daha az olan bir başka yaklaşım, hata eğilimli ve kavramsal olarak çok nasıl Haskell IO aslında davranır yakın
data ContIO = Exit | PutStrLn String ContIO | GetLine (String -> ContIO) | ...
main :: ContIO
main =
PutStrLn "what's your name?" $
GetLine $ \name ->
PutStrLn ("hi " name "!") $
Exit
Anahtarı "tembel listesi" gibi tepkiler büyük almak yerine bu ana başında argüman, kabul edip, tek tek istekleri yapıyoruz bir anda bir tartışma.
Bizim program şu anda sadece normal bir veri türü bağlı bir liste gibi bir şey dışında ...
RTS bazen main
, yorumlar sadece normal hareket edemez:
bir işlevi, o zaman hadi git tutan GetLine
gibi bir değer bulduğu
standart girdiden bir dize RTS büyü kullanarak, ve işleve dize geçmek,
devam etmeden önce. Egzersiz: interpret :: ContIO -> IO ()
Yazın.
Bu uygulamaların hiçbiri içeren not "dünya-geçer".
"dünya-geçen" Haskell O işleri ben/ne gerçekten değil. Gerçek
DZD IO
türü uygulama iç bir tür adı içerir
RealWorld
ama bu uygulama sadece bir detay.
IO
ekler gerçek Haskell bir tip eylemler yazabiliriz yani parametre
"ürün" rasgele değerler data IO a = Done a | PutStr String (IO a) | GetLine (String -> IO a) | ...
daha fazla gibi görünüyor. Bize daha fazla bilgi verir.
"keyfi üretmek "IO
eylemler yaratabiliriz çünkü esneklik,
değerler.
(Russell O'Connor points out,
bu tür sadece ücretsiz bir monad. Bunun için Monad
bir örneğini kolaylıkla yazabiliriz.)
Nerede monadlar o zaman geliyor? Monad
için ihtiyacımız yok çıkıyor
G/Ç ve devlet Monad
, peki neden ihtiyacımız olsun ki hiç ihtiyacımız yok? Bu
cevap vermiyoruz. Hiçbir şey türü Monad
sınıfı hakkında büyülü bir şey var.
IO
State
ile çalışırken ancak, (liste ve fonksiyonları ve
Maybe
ve devamı-geçen stil ve ...) ayrıştırıcıları yeterince uzun bir süre için, biz
sonunda onlar oldukça benzer şekilde bazı şekillerde davranan anlamaya. Olabiliriz
listedeki her dize yazdıran bir fonksiyon, ve çalışan bir fonksiyon yazın
liste ve bir iş parçacığı her duruma hesaplama devlet ve edecekler
birbirine çok benzer.
Benzer görünümlü bir sürü kod yazma gibi olmadığı için bir yol istiyoruz
bunu; Monad
bize izin verir, çünkü büyük bir soyutlama olur Özet
çok farklı görünen birçok çeşit soyut, ama yine de yararlı bir sürü sağlar
işlevsellik (Control.Monad
herşey dahil).
bindIO :: IO a -> (a -> IO b) -> IO b
verilen returnIO :: a -> IO a
,
monadlar hiç düşünmeden Haskell IO
herhangi bir program yazabilir. Ama
muhtemelen Control.Monad
,bir çok fonksiyonu çoğaltma biter
mapM
forever
when
(>=>)
.
Monad
ortak API uygulayarak, aynı kodu kullanıyoruz
ayrıştırıcıları ve listeler ile yaptığımız gibi, IO eylemleri ile çalışıyor. Gerçekten tek.
benzerlikler yakalamak için Monad
sınıf var akıl arasında
farklı türleri.
Nasıl bir şey kesilebilir devlet olmad...
Başka java ClassCastException atmak ne...
Nasıl dıv başka yanında değil aşağıda ...
Tanıtımı YABANCI ANAHTAR kısıtlaması d...
En iyi Windows Form içinde başka bir f...