Bu soruyu cevaplamak için daha sistematik bir yaklaşım önermek ve ayrıca "alt" değerler veya sonsuz veri türleri ya da bunun gibi herhangi bir özel numara kullanmayan örnekler göstermek istiyorum.
Yazım yapıcıları ne zaman yazım sınıfı örnekleri içeremez?
Genel olarak, bir tür yapıcısının belirli bir tür sınıfının bir örneğine sahip olamamasının iki nedeni vardır:
- Tür sınıfından gerekli yöntemlerin tür imzaları uygulanamıyor.
- Tip imzalarını uygulayabilir, ancak gerekli yasaları karşılayamaz.
Birinci türden örnekler ikinci türden daha kolaydır, çünkü ilk tür için, sadece belirli bir tip imzası olan bir işlevi yerine getirip getiremeyeceğini kontrol etmemiz gerekir, ikinci tür için ise hiçbir uygulamanın olmadığını kanıtlamamız gerekir. yasaları yerine getirebilirdi.
Özel örnekler
Bu, tür parametresine göre bir functor değil, bir kontrüktördür a, çünkü akontravaryant bir konumdadır. Tip imzalı bir fonksiyon uygulamak imkansızdır (a -> b) -> F z a -> F z b.
Türü imzası uygulanabilse fmapde yasal bir işlev olmayan bir tür oluşturucu :
data Q a = Q(a -> Int, a)
fmap :: (a -> b) -> Q a -> Q b
fmap f (Q(g, x)) = Q(\_ -> g x, f x) -- this fails the functor laws!
Bu örneğin meraklı yönü o zamanın olabilir uygulamak fmaprağmen doğru tipte Fkullandığı çünkü muhtemelen bir funktor olamaz abir kontravaryant konumda. Bu nedenle, fmapyukarıda gösterilen bu uygulama yanıltıcıdır - doğru tip imzasına sahip olmasına rağmen (bunun bu tip imzanın tek olası uygulaması olduğuna inanıyorum), functor yasaları tatmin olmuyor. Örneğin, fmap id≠ idçünkü let (Q(f,_)) = fmap id (Q(read,"123")) in f "456"olduğunu 123, ancak let (Q(f,_)) = id (Q(read,"123")) in f "456"bir 456.
Aslında, Fsadece bir profiktör, - ne bir fonktor ne de bir konfunktor.
Tür imzası uygulanamayacağı pureiçin geçerli olmayan yasal bir işlev : Yazar monadını alın (a, w)ve wbir monoid olması gereken kısıtlamayı kaldırın . Tür bir değer oluşturmak için daha sonra imkansız (a, w)üzerinden a.
Türünün imzası <*>uygulanamadığı için uygulanabilir olmayan bir işlevdata F a = Either (Int -> a) (String -> a) .
Tür sınıfı yöntemleri uygulanabilse bile yasal olarak geçerli olmayan bir işlevci :
data P a = P ((a -> Int) -> Maybe a)
Tür yapıcısı P, ayalnızca kovaryant konumlarda kullandığı için bir işlevcidir .
instance Functor P where
fmap :: (a -> b) -> P a -> P b
fmap fab (P pa) = P (\q -> fmap fab $ pa (q . fab))
Türünün imzasının tek olası uygulaması <*>her zaman dönen bir işlevdir Nothing:
(<*>) :: P (a -> b) -> P a -> P b
(P pfab) <*> (P pa) = \_ -> Nothing -- fails the laws!
Ancak bu uygulama, uygulamalı işlevler için kimlik yasasını karşılamamaktadır.
ApplicativeMonadTürü imzası binduygulanamadığı için olan ancak olmayan bir işlev .
Böyle bir örnek bilmiyorum!
- A funktor
Applicativeancak birMonad yasa türü imzası olsa memnun olamaz çünkü binduygulanabilir.
Bu örnek biraz tartışma yarattı, bu nedenle bu örneğin doğru olduğunu kanıtlamanın kolay olmadığını söylemek güvenlidir. Ancak birkaç kişi bunu farklı yöntemlerle bağımsız olarak doğruladı. Bkz. `Veri PoE a = Boş | Çifte bir monad mı? ek tartışma için.
data B a = Maybe (a, a)
deriving Functor
instance Applicative B where
pure x = Just (x, x)
b1 <*> b2 = case (b1, b2) of
(Just (x1, y1), Just (x2, y2)) -> Just((x1, x2), (y1, y2))
_ -> Nothing
Yasal bir Monadörnek olmadığını kanıtlamak biraz zahmetlidir . Monadik olmayan davranışın nedeni bind, bir fonksiyonun ne zaman f :: a -> B bgeri dönebileceği Nothingveya Justfarklı değerleri için uygulanmanın doğal bir yolu olmamasıdır a.
Belki Maybe (a, a, a)de bir monad olmayan düşünmek ve bunun için uygulamayı denemek daha açıktır join. Birisi sezgisel olarak makul bir uygulama yolu bulunmayacaktır join.
join :: Maybe (Maybe (a, a, a), Maybe (a, a, a), Maybe (a, a, a)) -> Maybe (a, a, a)
join Nothing = Nothing
join Just (Nothing, Just (x1,x2,x3), Just (y1,y2,y3)) = ???
join Just (Just (x1,x2,x3), Nothing, Just (y1,y2,y3)) = ???
-- etc.
İle belirtilen durumlarda , altı farklı tip değerden makul ve simetrik bir şekilde ???üretemeyeceğimiz açıktır . Kesinlikle bu altı değerin keyfi bir alt kümesini seçebiliriz - örneğin, her zaman ilk işsizliği alırız - ancak bu, monadın yasalarını karşılamaz. Geri dönmek de yasaları yerine getirmeyecektir.Just (z1, z2, z3)aMaybeNothing
- Ağaç benzeri bir veri yapısı , çağrışım yapmasına rağmen bir monad olmayan
bind - ancak kimlik yasalarında başarısız olur.
Her zamanki ağaç benzeri monad (veya "functor şekilli dalları olan bir ağaç")
data Tr f a = Leaf a | Branch (f (Tr f a))
Bu, functor üzerinde serbest bir monad f. Verilerin şekli, her dallanma noktasının alt ağaçların "işlev-ful" olduğu bir ağaçtır. Standart ikili ağaç ile elde edilir type f a = (a, a).
Bu veri yapısını yaprakları da functor şeklinde yaparak değiştirirsek f, "semimonad" dediğim şeyi elde ederiz - binddoğallığı ve ilişkilendirilebilirlik yasalarını tatmin eden, ancak pureyöntemi kimlik yasalarından birinde başarısız olur. "Semimonads endofunktor kategorisindeki yarıgruplar, sorun nedir?" Bu tip sınıfıdır Bind.
Basitlik için, joinyerine yöntem tanımlamak bind:
data Trs f a = Leaf (f a) | Branch (f (Trs f a))
join :: Trs f (Trs f a) -> Trs f a
join (Leaf ftrs) = Branch ftrs
join (Branch ftrstrs) = Branch (fmap @f join ftrstrs)
Dal aşılama standarttır, ancak yaprak aşılama standart değildir ve a üretir Branch. Bu, ilişkilendirilebilirlik yasası için bir sorun değildir, ancak kimlik yasalarından birini ihlal eder.
Polinom tiplerinde ne zaman monad örnekleri bulunur?
Her ikisi de functor Maybe (a, a)ve açıkça olsa da Maybe (a, a, a)yasal bir Monadörnek verilemez Applicative.
Bu işlevlerin hiçbir hilesi yoktur - hayır Voidveya bottomhiçbir yerde, zor tembellik / katılık, sonsuz yapılar ve tip sınıf kısıtlamaları yoktur. ApplicativeÖrneğin tamamen standarttır. Fonksiyonları returnve bindbu functors için uygulanabilir, ancak monad yasalarını yerine getirmez. Başka bir deyişle, belirli bir yapı eksik olduğu için bu işlevler monad değildir (ancak tam olarak neyin eksik olduğunu anlamak kolay değildir). Örnek olarak, işlevdeki küçük bir değişiklik onu bir monad haline getirebilir: data Maybe a = Nothing | Just abir monaddır. Başka bir benzer işlev data P12 a = Either a (a, a)de bir monaddır.
Polinom monadlar için inşaatlar
Genel olarak, burada Monadpolinom türlerinden yasal olanları üreten bazı yapılar var . Tüm bu yapılarda Mbir monad var:
type M a = Either c (w, a)wherhangi bir monoid nerede
type M a = m (Either c (w, a))mherhangi bir monad nerede ve wherhangi bir monoid
type M a = (m1 a, m2 a)nerede m1ve m2herhangi bir monad
type M a = Either a (m a)mherhangi bir monad nerede
İlk inşaat, WriterT w (Either c)ikinci inşaat WriterT w (EitherT c m). Üçüncü yapı monads bir bileşeni-bazlı üründür pure @Mbileşen-bazlı ürün olarak tanımlanır pure @m1ve pure @m2ve join @M(örneğin, çapraz-ürün verilerini atlanması ile tanımlanır m1 (m1 a, m2 a)eşleştirilir m1 (m1 a)başlığın ikinci kısmını iptal edilerek):
join :: (m1 (m1 a, m2 a), m2 (m1 a, m2 a)) -> (m1 a, m2 a)
join (m1x, m2x) = (join @m1 (fmap fst m1x), join @m2 (fmap snd m2x))
Dördüncü yapı şu şekilde tanımlanır:
data M m a = Either a (m a)
instance Monad m => Monad M m where
pure x = Left x
join :: Either (M m a) (m (M m a)) -> M m a
join (Left mma) = mma
join (Right me) = Right $ join @m $ fmap @m squash me where
squash :: M m a -> m a
squash (Left x) = pure @m x
squash (Right ma) = ma
Dört yapının da yasal monad ürettiğini kontrol ettim.
Ben varsayım polinom monads için başka yapılar olduğunu. Örneğin, Maybe (Either (a, a) (a, a, a, a))bu yapıların hiçbiri yoluyla işlev elde edilmez ve dolayısıyla monadik değildir. Ancak, Either (a, a) (a, a, a)bu üç monad'ların ürüne izomorftur çünkü monadic olduğunu a, ave Maybe a. Ayrıca, Either (a,a) (a,a,a,a)bu ürünü izomorftur çünkü monadic olduğunu ave Either a (a, a, a).
Yukarıda gösterilen dört yapı a, örneğin herhangi bir sayıdaki herhangi bir sayıda ürünün herhangi bir toplamını elde etmemizi sağlayacaktır Either (Either (a, a) (a, a, a, a)) (a, a, a, a, a)). Bu tür tüm yapıcıların (en az bir) Monadörneği olacaktır.
Tabii ki, bu tür monadlar için hangi kullanım durumlarının mevcut olabileceği görülüyor. Başka bir konu, Monad1-4 . Yapılarla türetilmiş örneklerin genel olarak benzersiz olmamasıdır. Örneğin, tip yapıcısına iki şekilde type F a = Either a (a, a)bir Monadörnek verilebilir : monad kullanılarak yapı 4 ile (a, a)ve izomorfizm türü kullanılarak yapı 3 ile Either a (a, a) = (a, Maybe a). Yine, bu uygulamalar için kullanım örnekleri bulmak hemen belli değildir.
Bir soru var - keyfi bir polinom veri türü verildiğinde, bir Monadörneğinin olup olmadığını nasıl anlayacağım . Polinom monadlar için başka yapı olmadığını nasıl kanıtlayacağımı bilmiyorum. Bu soruyu cevaplamak için şu ana kadar herhangi bir teori olduğunu düşünmüyorum.
* -> *) yapmak mümkün müdür ?fmap