Una descrizione matematica (categorica) delle classi di tipi


14

Un linguaggio funzionale può essere visto come una categoria in cui i suoi oggetti sono tipi e funzioni di morfismi tra loro.

Come si adattano le classi di tipi in questo modello?

Presumo che dovremmo considerare solo quelle implementazioni che soddisfano il vincolo che hanno la maggior parte delle classi di tipi, ma che non sono espresse in Haskell. Ad esempio, dovremmo considerare solo quelle implementazioni Functorper le quali fmap id ≡ ide fmap f . fmap g ≡ fmap (f . g).

Oppure ci sono altre basi teoriche per le classi di tipi (ad esempio basate su calcoli lambda tipizzati)?


1
Potresti voler essere più esplicito su ciò per cui desideri un modello. Se vuoi qualcosa che possa descrivere rigorosamente il presupposto del mondo aperto, il comportamento della risoluzione dell'istanza, l'interazione di varie estensioni GHC, ecc., È piuttosto più complicato di una versione idealizzata. Allo stesso modo, si noti che i fondi vengono spesso ignorati quando si discute di Hask.
CA McCann,

4
Le classi di tipi possono essere pensate come firme (nel senso dell'algebra universale). La raccolta di tutte le entità che condividono la stessa firma (elementi della stessa classe di tipo) è una varietà .
Dave Clarke,

1
@DaveClarke: Non è immediatamente ovvio per me come descrivere le classi di tipi su tipi superiori in quel modo, ma non ho una grande familiarità con l'algebra universale e potrei fraintendere la corrispondenza che hai in mente ...
CA McCann,

1
@camccann: non sono sicuro di quanto va lontano la corrispondenza. Sembrava sicuramente un buon punto di partenza.
Dave Clarke,

2
@camccann: basta cambiare la categoria di base su cui si sta definendo la tua algebra: le classi di tipo base come num sono firme sulla categoria di tipi haskell (o oggetti della categoria Hsk), le classi di tipo sui costruttori di tipo sono algebre sulla categoria di funzioni da Hask a Hask. Si noti che l'algebra universale è completamente inclusa nella nozione di algebra nella teoria delle categorie. Inoltre: Dave: dovresti trasformare il tuo commento in una risposta.
cody

Risposte:


18

Come si adattano le classi di tipi in questo modello?

La risposta breve è: non lo fanno.

Ogni volta che si introducono coercizioni, classi di tipi o altri meccanismi per il polimorfismo ad hoc in un linguaggio, il principale problema di progettazione che si incontra è la coerenza .

Fondamentalmente, è necessario assicurarsi che la risoluzione della typeclass sia deterministica, in modo che un programma ben tipizzato abbia una singola interpretazione. Ad esempio, se potessi fornire più istanze per lo stesso tipo nello stesso ambito, potresti potenzialmente scrivere programmi ambigui come questo:

class Blah a where
   blah : a -> String 

instance Blah T where
   blah _ = "Hello"

instance Blah T where
   blah _ = "Goodbye"

v :: T = ...

main :: IO ()
main = print (blah v)  -- does this print "Hello" or "Goodbye"?

A seconda della scelta dell'istanza effettuata dal compilatore, blah vpotrebbe essere uguale a "Hello"o "Goodbye". Pertanto, il significato di un programma non sarebbe completamente determinato dalla sintassi del programma, ma piuttosto potrebbe essere influenzato da scelte arbitrarie fatte dal compilatore.

La soluzione di Haskell a questo problema è richiedere che ogni tipo abbia al massimo un'istanza per ogni classe di caratteri. Per garantire ciò, consente dichiarazioni di istanza solo al livello più alto e rende inoltre visibili tutte le dichiarazioni a livello globale. In questo modo, il compilatore può sempre segnalare un errore se viene fatta una dichiarazione di istanza ambigua.

Tuttavia, rendere le dichiarazioni visibili a livello globale interrompe la compositività della semantica. Quello che puoi fare per recuperare è dare una semantica di elaborazione per il linguaggio di programmazione, cioè puoi mostrare come tradurre i programmi Haskell in un linguaggio più educato e più compositivo.

Questo in realtà ti dà un modo per compilare anche le macchine da scrivere - di solito viene chiamata "traduzione delle prove" o "trasformazione del passaggio del dizionario" nei circoli di Haskell ed è una delle prime fasi della maggior parte dei compilatori di Haskell.

Le typeclass sono anche un buon esempio di come il design del linguaggio di programmazione differisce dalla pura teoria dei tipi. Le macchine da scrivere sono una caratteristica del linguaggio davvero eccezionale, ma sono abbastanza maleducate dal punto di vista della teoria delle prove. (Ecco perché Agda non ha affatto le macchine da scrivere e perché Coq le rende parte della sua infrastruttura euristica di inferenza.)


qual è il secondo classificato candidato che non ha semantica denotazionale iyswim?
Ohad Kammar,

1
Purtroppo non ho idea.
Neel Krishnaswami,

Questo merita una domanda aggiuntiva?
Ohad Kammar,

@NeelKrishnaswami: hai idea di come i moduli ML si adattino a questo? E i moduli Agda (che qualcuno mi ha menzionato sono "di prima classe")?
Lii,

1
@Lii: i moduli ML e i record Agda sono molto più educati, ma è troppo complicato spiegarli in un commento - fai una domanda su di loro, e io (o qualcun altro) spiegherò.
Neel Krishnaswami il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.