2014-05-15 13 views
8

W dokumentacji dla Data.Functor następujące dwa są określone jako prawa funktora, do których mają się stosować wszystkie funktory.Czy prawa funktora udowadniają całkowitą ochronę struktury?

fmap id == id 
fmap (f . g) == fmap f . fmap g 

Droga moja intuicja mówi mi funktory powinien pracować jest to, że powinny one być „struktura zachowania”, czyli innymi słowy, jeśli masz funkcję f :: a -> b i to odwrotność g :: b -> a następnie

fmap f . fmap g == id 

Nie byłem w stanie wymyślić implementacji fmap, która byłaby zgodna z pierwszymi dwoma prawami i naruszała drugą, ale to nie jest żaden dowód. Czy ktoś może mnie oświecić?

+0

+1 Ostatnio zmagałem się z podobnymi pytaniami. Jest jedna rzecz, która przeszkadza mi w tym intuicyjnym sformułowaniu: co z funkcjami bez odwrotności? Z pewnością 'fmap (const" Foo ")' jest w pewnym sensie zachowujący strukturę? – duplode

+0

Tak, ale nie możesz użyć 'const" Foo "' do potwierdzenia prawdziwości prawa - musisz wybrać inną funkcję. Nie mówię, że funktory są ważne tylko w odniesieniu do funkcji, jakie obejmuje prawo. – kqr

+0

@duplode wyobrazić sobie drzewo danych drzewa a = liść | Węzeł a [Drzewo a] '. Kiedy mówimy o "strukturze" 't :: Tree a', myślimy o tym, jak wiele poddrzew ma każdy węzeł i jak są one zorganizowane. Można więc powiedzieć, że jesteśmy zainteresowani 't' z _okolwiek w jego węzłach_. I rzeczywiście możemy to uchwycić za pomocą 'fmap (const()) t'. – fizruk

Odpowiedz

13

Właściwie swoją „trzecią” Prawo funktor wynika bezpośrednio z faktycznym prawem funktorów oraz fakt, że f . g ≡ id:

fmap f . fmap g ≡ fmap (f . g) ≡ fmap id ≡ id 

A to nie wszystko: Haskell zapewnia, że ​​jeśli pierwsza zasada odnosi się do Functor instancji, a następnie drugi również posiada (jest to darmowe twierdzenie dla typu fmap). To znaczy. musisz udowodnić tylko prawo fmap id ≡ id dla swojej instancji Functor, aby upewnić się, że jest poprawna.

+0

Kiedy 'f. g ≡ id', czy zarówno funkcja 'f', jak i' g' mają jakiś matematyczny termin opisujący ich związek? (Myślę, że gdzieś czytam o izomorfizmie, ale nie jestem pewien.) – Sibi

+1

@Sibi: dlaczego, tak, 'f' jest lewostronnym przeciwieństwem' g' i 'g' jest prawą odwrotnością' f'. Nie oznacza to jednak izomorfizmu domeny i kodomeny żadnej z tych funkcji, na przykład 'show :: Int -> String' ma" odczyt "jako lewostronną, chociaż" Int "ma oczywiście mniejszą liczność niż" String ". – leftaroundabout

+7

@Sibi Zwróć uwagę, że 'f. g ≡ id' nie implikuje 'g. f ≡ id'. Jeśli jednak tak jest, obie funkcje nazywają się "izomorfizmami" _. W przeciwnym razie, 'f' jest nazywane _" wycofaniem "_ (lub _" lewostronnym odwrotnością "g" "_) a" g "jest nazywane _" section "_ (lub _" right inverse of "f" "_). – fizruk

Powiązane problemy