Aradığınız tanım okur biz oraya nasıl oldu
Concurrent h >>= k = Concurrent (\f -> h (\x -> runConcurrent (k x) f))
gibi bir şey? Her zaman olduğu gibi, türlerin işi yapmasına izin veriyoruz. , Sonra hedeftir sen
h :: (a -> Action) -> Action
ve
k :: a -> Concurrent b
ile tanımına
Concurrent h >>= k = ...
sol tarafı ile başlarsanız
runConcurrent :: Concurrent b -> (b -> Action) -> Action
runConcurrent (Concurrent h) = h
: :)
bize ilk bir yardımcı işlevi tanıştırayım ...
'u Concurrent b
türünde bir ifadeyle değiştirmek için değil mi?
Concurrent b
türünde bir değeri nasıl oluşturabiliriz? Bir yol k
işlevimizi uygulamaktır, ancak bu çalışmaz, çünkü argüman olarak kullanılabilir a
türünde uygun bir değere sahip değiliz. Yani, yapabileceğimiz tek şey, ((b -> Action) -> Action) -> Concurrent b
tipindeki Concurrent
veri yapısını uygulamaktır.
verir Yani:
Concurrent h >>= k = Concurrent ...
Şimdi gidip bize
Concurrent
için bir argüman olarak tedarik tip
(b -> Action) -> Action
bir ifadeyi bulmak zorundayız. Biz fonksiyonu Çeşidi ifadeler her zaman lambda-soyutlama yoluyla inşa edilebileceğini biliyoruz:
Concurrent h >>= k = Concurrent (\f -> ...)
Bu bize tip Action
bir anlatımda ile ...
yerine f :: b -> Action
ve yükümlülüğünü verir. Action
-şarktörlerinden birini doğrudan kullanmak elbette hile yapar;). (>>=)
(daha kesin olarak, monad yasalarına uymak zorunda olduğumuzdan emin olmak için) jenerikliğini garanti etmek için, Action
, soyut bir veri türü gibi davranırız. Bir sonraki biz tip a -> Action
bir argümanla h
sağlamanız gerekmektedir, Bu nedenle
Concurrent h >>= k = Concurrent (\f -> h ...)
: Sonra, bir Action
-Değer üretmek için tek yol fonksiyonunu h
uygulamaktır. Bir daha bir fonksiyon tipi, bu nedenle başka bir lambda atmak:
Concurrent h >>= k = Concurrent (\f -> h (\x -> ...))
Dolayısıyla, x :: a
ve tip Action
bir gövde oluşturmak gerekir. a
türünde bir değerle neler yapabiliriz?Bunu k
işlevine sağlayabiliriz. Bu bize daha sonra bizim yardımcı işlevi runConcurrent
için geçebilir tip Concurrent b
, değerini verir:
Concurrent h >>= k = Concurrent (\f -> h (\x -> runConcurrent (k x) ...))
Bu hile bize tip (b -> Action) -> Action
bir işlev verir ve bağımsız değişken olarak f
tedarik yapar:
Concurrent h >>= k = Concurrent (\f -> h (\x -> runConcurrent (k x) f))
Analizleriniz yanlış. 'x'' b -> Action' türüne sahiptir, 'b' değil. – bennofs
[Free Monad] 'a göz atmak isteyebilirsiniz (http://stackoverflow.com/questions/13352205/what-are-free-monads). Rasgele tekrar edilebilen bir monad kaydetmenize izin verir. Hafif iplikler için kullandım. – Franky