kullanıcı 'singpolyma' asked on reddit orada yatan bazı genel yapısı ise: Ücretsiz bir monad önerildiUygulama sirkülasyonlarının bileşimi aracılığıyla kısa devre arızasıyla başarıların listesini oluşturabilir miyim?
data FailList a e = Done | Next a (FailList a e) | Fail e
, ancak bu uygulamalı functors aracılığıyla daha genel model alınarak belirlenebileceğini merak ettim. Bazerman, Abstracting with Applicatives numaralı telefondan bize, iki uygulamalı funktörün toplamının, önyargı doğrultusunda doğal bir dönüşüme sahip olmamız koşuluyla, sol/sağa eğilimli, uygulamalı bir functor olduğunu göstermektedir. Bu ihtiyacımız olan şey gibi geliyor! Böylece teklifime başladım, ancak daha sonra hızla problemlerle karşılaştım. Herkes bu sorunlara çözümler görüyor mu ?:
İlk olarak, iki çekicinin toplamının tanımıyla başlıyoruz. Buraya başladım çünkü toplam türlerini modellemek istiyoruz - başarılar ya da başarılar ve başarısızlık.
data Sum f g a = InL (f a) | InR (g a)
Ve çalışmak istediğiniz iki fanktorlar şunlardır:
data Success a = Success [a]
data Failure e a = Failure e [a]
Success
basittir - aslında Const [a]
bu. Ancak, Failure e
Bundan emin değilim. pure
herhangi bir tanıma sahip olmadığı için, uygulama amaçlı bir eğlence aracı değildir.
instance Functor Success where
fmap f (Success a) = Success a
instance Functor (Failure e) where
fmap f (Failure e a) = Failure e a
instance Apply (Failure e) where
(Failure e a) <.> (Failure _ b) = Failure e a
instance Apply Success where
(Success a) <.> (Success b) = Success (a <> b)
instance Applicative Success where
pure = const (Success [])
a <*> b = a <.> b
Daha sonra, sağdan sola doğru doğal bir dönüşüm ile, bu functors toplamını tanımlayabilir (yani sol ön gerilim):
instance (Apply f, Apply g, Applicative g, Natural g f) => Applicative (Sum f g) where
pure x = InR $ pure x
(InL f) <*> (InL x) = InL (f <*> x)
(InR g) <*> (InR y) = InR (g <*> y)
(InL f) <*> (InR x) = InL (f <.> eta x)
(InR g) <*> (InL x) = InL (eta g <.> x)
Ancak, Apply bir örneğidir Ve şimdi yapmamız gereken tek şey, doğal dönüşümümüzü tanımlamaktır ve burası her şeyin çöküşüdür.
instance Natural Success (Failure e) where
eta (Success a) = Failure ???? a
oluşturmak için yetersizlik bir Failure
sorun gibi görünüyor. Ayrıca, hacky olmak ve ⊥ kullanmak bir seçenek değildir, çünkü bu , InR (Success ...) <*> InL (Failure ...)
bulunduğunuz durumda değerlendirilecektir.
Bir şeyleri kaçırıyormuş gibi hissediyorum, ama ne olduğu hakkında hiçbir fikrim yok.
Bu yapılabilir mi?
Doğallık koşulu forall (f :: a -> b). eta. fmap f == fmap f. eta, hata bileşeninin sabit olması gerektiğini kuvvetle önerir. Bu bana bir 'Varsayılan e => Uygulayıcı (Başarısız e)' yazmamı sağlıyor. –
Ayrıca, Uygulamanızın/Uygulamanızın örnekleri tuhaf. Kafaları sıkıca kontrol ettim, ama genelde tip kontrol etmiyorlar! 'Başarı a' aslında 'Sabit [a]' ya değil, en azından, daha fazla tip indekslere ihtiyaç duyar. –
@tel - 'Varsayılan 'mümkün görünüyor, sadece bir aklı başında" varsayılan hata mesajı "olacağını göremiyorum. Ayrıca, düzenlemeleriniz geçerli olmakla birlikte diğer SO editörleri tarafından reddedildi. Onları kendim uygularım. – ocharles