2013-02-11 7 views
16

Per quanto ho capito, un functor è una mappatura tra due categorie, ad esempio da oggetti in C http://mathurl.com/32qch9w.png a oggetti in D http://mathurl.com/36b8r37.png dove C http://mathurl.com/32qch9w.png e D http://mathurl.com/36b8r37.png sono categorie.In che modo i functor in Haskell sono correlati ai funtori nella teoria delle categorie?

In Haskell c'è Hask in cui gli oggetti sono tipi Haskell ei morfismi sono funzioni Haskell. Tuttavia, il tipo di classe Functor dispone di una funzione che mappa fmap tra questi tipi (che sono quindi gli oggetti e non categorie stessi):

fmap :: (a -> b) -> f a -> f b 

f a e f b sono entrambi gli oggetti in Hask. Significa che ogni istanza di Functor in Haskell è un endofunctor e, in caso contrario, Functor rappresenta davvero un funtore?

Cosa mi manca qui? I tipi sono anche categorie in Haskell?

risposta

23

un'istanza di Functor specifica due cose: un tipo costruttore F di tipo * -> *, cioè una mappatura da oggetti di Hask ad oggetti di Hask, e una funzione di tipo (a -> b) -> (F a -> F b), cioè una mappatura da frecce di Hask alle frecce di Hask compatibili con la mappatura degli oggetti F. Quindi, sì, tutte le istanze di Functor sono endofunzionisti. Esistono diverse generalizzazioni disponibili su Hackage, ad es. Control.Categorical.Functor.

+0

Si dice * le frecce di Hask compatibili con il mapping di oggetti 'F' *. È una sottocategoria di Hask? –

+2

@Zoidberg Yup, è la sottocategoria di Hask i cui oggetti sono i tipi il cui costruttore di tipo più esterno è 'F'. –

+0

Ho capito bene: teoricamente questi endofuncori non devono necessariamente lavorare su tipi con tipo '* -> *', voglio dire che functor potrebbe mappare una funzione 'Int -> Char' per funzionare' String -> Double'. Come ho capito, in teoria i funtori lavorano su qualsiasi morfismo. Ma immagino che non sia troppo pratico. O sono completamente sbagliato qui? – dimsuz

15

Sì, tutte le istanze sono Functor endofunctors su Hask --in infatti, endofunctors da tutti Hask ad una sottocategoria appropriata i cui oggetti sono i tipi ottenuti mediante l'applicazione di un particolare tipo di costruzione. Quel tipo di costruttore è ciò che è associato all'istanza Functor e fornisce il mapping per gli oggetti; la mappatura dei morfismi è fmap, che (poiché ci occupiamo solo di endofuncori in una categoria chiusa cartesiana) è di per sé una famiglia di morfismi in Hask.

Ha senso prendere in considerazione altre funtori oltre a quelli che può avere Functor casi, come ad esempio contravariant functors (da Hask alla sua categoria opposto). La funzione arr in the Arrow class corrisponde anche ad un funtore, da tutti Hask alla categoria cui oggetti sono identici a quelli di Hask ei cui morfismi sono descritte dal costruttore tipo dell'istanza Arrow è associato.

Ulteriori generalizzazioni sono anche possibili (come osserva Daniel Wagner), ma tendono a diventare sempre più scomode da usare.

4

Un punto importante di questo è che ciò che si vuole veramente è funtori arricchiti in Hask, non semplicemente vecchio funtori. Hask è cartesiano chiuso (not really, ma prova a essere un po 'duro), e quindi è naturalmente arricchito di per sé.

Ora, endofunctors arricchiti vi danno un modo di limitare a quelli implementabile all'interno del linguaggio: un funtore arricchito Hask -> Hask è una funzione a livello di oggetti (tipi) f a e per ogni coppia di oggetti a, b un morfismo in Hask andare f: Hask (a, b) ->Hask (FA, FB). Naturalmente, questo è solo fmap :: (a -> b) -> f a -> f b