2013-11-04 28 views
21

Exercise 5 of the Haskell Typeclassopedia Section 3.2 iki functors kompozisyonu aynı zamanda bir Funktör olan deyimiİki Functor oluşturmanın anlamı nedir?

bir kanıtı veya kar¸ıt sorar.

Bunun Functor iki ayrı örnekleri tarafından tanımlanan fmap yöntemleri beste bahsettiği ilk başta düşündüm ama tipleri kadarıyla I olarak maç olmaz çünkü o gerçekten mantıklı değil söyleyebilir. Iki çeşit f ve f' için, fmap türleri fmap :: (a -> b) -> f a -> f b ve fmap :: (a -> b) -> f' a -> f' b olur ve bu gerçekten composable görünmüyor. Yani iki Functors oluşturmak ne demektir? türlerine tip seviye haritalama türlerinde birini (bu instance Functor x where içinde x olan) ve işlevlerine süreli seviyesi haritalama fonksiyonları üzerindeki birini (bu fmap = x içinde x olan):

+2

Gerçekten fmap'i kendisiyle birlikte ghci içinde oluşturmayı denediniz mi? yani: fmap. fmap' – Squidly

+0

@MrBones Bahşiş için teşekkürler! Ghci erişimi olmayanlar için, çıktı ':: (Functor f1, Functor f) => (a -> b) -> f (f1 a) -> f (f1 b)' – akbiggs

cevap

24

A Functor iki eşleştirmeleri verir. Dönem düzeyinde haritalamayı oluşturmayı düşünüyorsunuz, ancak tür düzeyinde haritalamayı oluşturmayı düşünmelisiniz; örneğin

data Compose f g x = Compose (f (g x)) 

Eğer

instance (Functor f, Functor g) => Functor (Compose f g) 

yazabilir verilen? Değilse neden olmasın?

+1

Bu bir Çözüm vermeden Typeclassopedia egzersiz açıklayan mükemmel bir cevap. – Will

11

başka işlev içinde bir işlev koymak iki fonksiyonların kompozisyon,

round (sqrt 23) 

gibi bu iki fonksiyon round ve sqrt bileşimi. Aşağıdaki gibi

Just [3, 5, 6, 2] 

Liste bir funktoru olduğu başka functor içine bir functor koymak ve böylece Belki olduğunda Benzer şekilde, iki funktorlar bileşimi olduğunu. Eğer fmap'in yukarıdaki değere ne yapması gerektiğini anlamaya çalışırsanız, kompozisyonlarının neden bir de functor olduğu konusunda sezgiler alabilirsiniz. Tabii ki içsel functor'ın içeriği üzerinde haritalanmalıdır! Gerçekten burada kategorik yorumuna düşünmeye yardımcı olur

12

, bir funktor F: C -> D bir kategoride D nesnelere ve Morfizm bir kategori C nesneler (değerler) ve nesnelere ve Morfizm için morfizimler (fonksiyonlar) sürer. ikinci funktor G : D -> E functors G . F : C -> E bileşimi için

sadece G fmap dönüşüm etki alanı olarak F fmap dönüşümün değer kümesi alıyor. Haskell'de bu biraz yeni bir tür unwrapping ile gerçekleştirilir.

import Data.Functor 

newtype Comp f g a = Comp { unComp :: f (g a) } 

compose :: f (g a) -> Comp f g a 
compose = Comp 

decompose :: Comp f g a -> f (g a) 
decompose = unComp 

instance (Functor f, Functor g) => Functor (Comp f g) where 
    fmap f = compose . fmap (fmap f) . decompose 
+2

Hey! Spoiler yasak! = P –

+1

'f'' functor' ve 'function''a aynı anda mı atıfta bulunur? Cevabınız evet ise, o zaman neden 'Functor f' türündeki kısıtlama' f' f 'f' için geçerli değildir? – Kamel

12

ne bundan bahsetmiyor tipi kurucular [] ve Maybe, fmap gibi fonksiyonların değil kompozisyon gibi bileşimi olduğunu.

newtype ListOfMabye a = ListOfMaybe [Maybe a] 
newtype MaybeOfList a = MaybeOfList (Maybe [a]) 

açıklamada iki Functors bileşimi bir Functor Bu tip bir Functor örneği yazma bir kalıplaşmış yolu var demektir olduğu: Yani, örneğin, [] ve Maybe yazmanın iki yolu vardır

: Aslında
instance Functor ListOfMaybe where 
    fmap f (ListOfMaybe x) = ListOfMaybe (fmap (fmap f) x) 

instance Functor MaybeOfList where 
    fmap f (MaybeOfList x) = MaybeOfList (fmap (fmap f) x) 

, Haskell Platformu bu "ücretsiz" yapan Compose türünü verir modül Data.Functor.Compose ile geliyor

import Data.Functor.Compose 

newtype Compose f g a = Compose { getCompose :: f (g a) } 

instance (Functor f, Functor g) => Functor (Compose f g) where 
    fmap f (Compose x) = Compose (fmap (fmap f) x) 

ComposeGeneralizedNewtypeDeriving uzantısı ile özellikle faydalıdır: İki Applicative s bileşimi, aynı zamanda, bir Applicative olan

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

newtype ListOfMaybe a = ListOfMaybe (Compose [] Maybe a) 
    -- Now we can derive Functor and Applicative instances based on those of Compose 
    deriving (Functor, Applicative) 

Not olduğu. Bu nedenle, [] ve Maybe, Applicative s olduğu için Compose [] Maybe ve ListOfMaybe'dur. Applicative s besteleri, monadların tam gücüne ihtiyaç duymadığınız durumlarda monad transformatörlerine alternatif olarak, günümüzde yavaşça daha yaygın hale gelen gerçekten düzgün bir tekniktir.

+0

Şüphesiz, burada tüm cevapların en kullanışlıdır. Daha fazla sormama izin verin: fmap f (Compose x) yazdığınızda x'in türü nedir? Ben şunu söyleyeyim, ama yine de hesaplamayı görselleştirmek için mücadele ediyorum (fmap (fmap f) x). GetCompose hakkında daha fazla düşünmeliyim. NB: "f" harfinin burada iki farklı rolde kullanıldığını anlıyorum. –