SequenceA çift listeleri üzerinde nasıl çalışır?
Bu sorudan dönün . Sezgisel olarak, bu kullanım durumunda ne olduğunu anladım sequenceA, ancak nasıl / neden böyle çalıştığını anlamadım .
Öyleyse hepsi şu soruya geliyor: sequenceAAşağıdaki durumda nasıl çalışır?
> sequenceA [("a",1),("b",2),("c",3)]
("abc",[1,2,3])
görüyorum
sequenceA :: (Traversable t, Applicative f) => t (f a) -> f (t a)
bu nedenle yukarıdaki USECASE içinde Traversableolan []ve Applicative, çünkü (,)ikili bir tipte olduğu, olduğu (,) a, ki parite üzerinde uygulamalı bir funktor olarak alınması araçları sndalanında. Ve bu snd, sonuçta biten liste birlikte gider . Böylece, bir çift listesinden, ikinci alanında bir liste bulunan bir çifte gidiyoruz.
Ama nereden "abc"geliyor? Demek istediğim, bunun fsttüm çiftlerin birleştirilmesi olduğunu biliyorum , ancak bunun s listesi aracılığıyla mı ++yoksa aracılığıyla mı olduğunu bilmiyorum . Çiftlerin e'lerinin bir araya getirilebilmesini sağlayacak hiçbir şeyin imzası yok gibi görünüyor .concatfstsequenceAfst
Yine de bu varsayımın bir yerde kullanılması gerekiyor. Aslında, aşağıdakiler başarısız olur
sequenceA [('a',1),('b',2),('c',3)]
Yanıtlar
Haskell'de, bir tür için tip sınıfı örnekleri, türün bölümleri için diğer tip sınıfı örneklerinin varlığına bağlı olarak "koşullu" olabilir. Değil tüm formun tipi kurucular ((,) a)örnekleri olan Applicative, ancak sadece bu kendisi için atip bir sahiptir Monoidörneği.
Bu gerekli kısıtlamalar =>örneğin Haddock'larından önce şu şekilde görünür :
Monoid a => Applicative ((,) a)
MonoidÖrnek neden gereklidir? İlk olarak, pureiçin ((,) a)gereken bir gerçekleştirmek için abaşlığın birinci elemanın koymak için ince hava değerini. memptytip aiçin işi yapar.
Birkaç seviye derinliğinde gerekli kısıtlama zincirleri olabilir. Örneğin aşağıdakiler neden çalışıyor?
ghci> import Datta.Function ((&)) -- flipped application
ghci> [(id :: String -> String, 2 :: Int), (\x -> x ++ x, 1)] & sequenceA & fst $ "foo"
"foofoofoo"
Burada ilk bileşen bir fonksiyondur. Daha önce olduğu gibi, çalışması Monoidiçin bir örneğe sahip olması gerekir sequenceA. Ama ne zaman a -> ba tipi Monoid? Haddocks'a baktığımızda şunları buluyoruz:
Monoid b => Monoid (a -> b)
Yani, Monoiddönüş türü (burada String) a olduğunda işlevler 'dir Monoid.
Aslında, yeni tür aracılığıyla kullanılabilen işlevler için başka bir Monoid örnek daha var Endo. Belirli bir işlem için hangi örneğin kullanılacağını seçmek için yeni türlerin kullanılması yaygındır, ancak bir miktar sarma ve sarmayı açma gerektirir.
Kullanır mappend. Kullandığı Applicativeörnek şuna benzer:
instance Monoid a => Applicative ((,) a) where
pure x = (mempty, x)
(af, f) <*> (ax, x) = (mappend af ax, f x)