2011-10-04 12 views
17

This paper stabilisce che l'inferenza di tipo (detta "tipabilità" nella carta) nel sistema F è indecidibile. Quello che non ho mai sentito nominare altrove è il secondo risultato del documento, ovvero che "il controllo del tipo" in F è anche indecidibile. Qui la domanda "verifica tipo" significa: dato un termine t, tipo T e ambiente di scrittura A, è il giudizio A ⊢ t : T derivabile? Che questa domanda sia indecidibile (e che sia equivalente alla questione della tipabilità) è sorprendente per me, perché sembra intuitivamente come dovrebbe essere una domanda più facile a cui rispondere.Esistono firme di tipi che Haskell non è in grado di verificare?

Ma in ogni caso, visto che Haskell è basato sul sistema F (o F-omega, anche), il risultato sul tipo di controllo sembrerebbe suggerire che ci sia un termine Haskell t e digitare T in modo tale che il compilatore essere in grado di decidere se t :: T è valido. Se è così, sono curioso di sapere che tipo di termine e tipo sono ... se non è il caso, che cosa sto fraintendendo?

Presumibilmente comprendere la carta porterebbe ad una risposta costruttiva, ma io sono un po 'fuori dalla mia profondità :)

+5

Haskell utilizza un'edizione * resitricted * di System F denominata [* Hindley Milner *] [http://en.wikipedia.org/wiki/Hindley-Milner]. AFAIK è possibile dedurre il tipo di qualsiasi espressione che ha un tipo. Rendere impossibile il controllo dei tipi è una questione di attivare estensioni strane abbastanza. – fuz

+2

@FUZxxl: Credo che abilitando solo 'RankNTypes' e' ImpredicativeTypes' si abbia tutta la potenza di System F (e poi alcuni, dato che Haskell supporta anche l'astrazione su operatori di tipo). –

+1

Questo è quello che ho cercato di dire "Rendere impossibile il controllo dei tipi è una questione di accensione di estensioni strane". – fuz

risposta

3

Ecco un esempio di implementazione di livello tipo di calcolo SKI a Scala: http://michid.wordpress.com/2010/01/29/scala-type-level-encoding-of-the-ski-calculus/

L'ultimo esempio mostra una iterazione illimitata. Se fai lo stesso in Haskell (e sono abbastanza sicuro che puoi farlo), hai un esempio di "espressione non classificabile".

+0

Mi piacerebbe vedere l'equivalente in Haskell. –

+0

@Dan Burton: http://www.haskell.org/haskellwiki/Type_SK –

11

Il controllo del tipo può essere reso decidibile arricchendo opportunamente la sintassi. Ad esempio, nel documento, abbiamo lambda scritto come \x -> e; per digitare-verificare, è necessario indovinare il tipo di x. Tuttavia, con una sintassi opportunamente arricchita, questo può essere scritto come \x :: t -> e invece, che risolve il problema. Allo stesso modo, nel documento, consentono ai lambda di livello testo di essere impliciti; ovvero, se e :: t, quindi anche e :: forall a. t. Per eseguire il controllo ortografico, devi indovinare quando e quanti forall aggiungere e quando eliminarli. Come in precedenza, si può fare questo più deterministico con l'aggiunta di sintassi: aggiungiamo due nuovi espressione forma /\a. e e e [t] e due nuova regola di battitura che dice che se e :: t, poi /\a. e :: forall a. t, e se e :: forall a. t, quindi e [t'] :: t [t'/a] (dove le parentesi in t [t'/a] sono parentesi di sostituzione). Quindi la sintassi ci dice quando e quante forche aggiungere e quando eliminarle.

Quindi la domanda è: possiamo passare da Haskell a termini di sistema F sufficientemente annotati? E la risposta è sì, grazie ad alcune restrizioni critiche poste dal sistema di tipo Haskell. Il più critico è che tutti i tipi sono di prima scelta *. Senza entrare troppo nel dettaglio, "rank" è relativo al numero di volte che devi andare a sinistra di un costruttore -> per trovare uno forall.

Int -> Bool -- rank 0? 
forall a. (a -> a) -- rank 1 
(forall a. a -> a) -> (forall a. a -> a) -- rank 2 

In particolare, questo limita il polimorfismo un po '. Non possiamo digitare qualcosa di simile con i tipi di rango uno:

foo :: (forall a. a -> a) -> (String, Bool) -- a rank-2 type 
foo polymorphicId = (polymorphicId "hey", polymorphicId True) 

La prossima restrizione più critico è che le variabili di tipo possono essere sostituite solo da tipi monomorfa. (Questo include altre variabili di tipo, come a, ma non tipi polimorfi come forall a. a.) Ciò garantisce in parte che la sostituzione di tipo conserva la rank-one-ness.

Si scopre che se si effettuano queste due restrizioni, quindi non solo è decidibile il tipo-inferenza, ma si ottiene anche minimo tipi.

Se passiamo da Haskell a GHC, possiamo parlare non solo di cosa è tipabile, ma di come appare l'algoritmo di inferenza. In particolare, in GHC, ci sono estensioni che rilassano le due precedenti restrizioni; in che modo GHC fa l'inferenza in quell'impostazione? Bene, la risposta è che semplicemente non ci prova nemmeno. Se vuoi scrivere termini usando queste caratteristiche, devi aggiungere le annotazioni di battitura di cui abbiamo parlato fino al paragrafo 1: devi annotare esplicitamente dove forall s viene introdotto ed eliminato. Quindi, possiamo scrivere un termine che rifiuta il type-checker di GHC? Sì, è semplice: usa semplicemente tipi o impraticabilità di secondo grado non annotati (o superiori). Ad esempio, il seguente non digitare-controllo, anche se ha un tipo di annotazione esplicita ed è tipizzabile con rango di due tipi:

{-# LANGUAGE Rank2Types #-} 
foo :: (String, Bool) 
foo = (\f -> (f "hey", f True)) id 

* In realtà, limitando di rango due è sufficiente a rendere decidibile, ma l'algoritmo per i tipi di rango uno può essere più efficiente. Classificare tre tipi già fornisce al programmatore una corda sufficiente a rendere il problema di inferenza indecidibile. Non sono sicuro che questi fatti fossero noti al momento in cui il comitato ha scelto di limitare Haskell ai tipi di grado 1.

+3

Re. "Quindi la domanda è:" ... no, in realtà non è la domanda. Non ho chiesto se annotando i parametri di funzione o limitando il polimorfismo di grado 2 possiamo rendere decidibile il controllo di tipo; So che la risposta è sì. La mia domanda è, puoi esporre un termine 't' e digitare' T' tale che 't :: T' confonde il correttore di tipi. Avrei dovuto chiarire che 't' dovrebbe essere un termine nel calcolo lambda non tipizzato (non dovrebbe contenere attribuzioni di tipo), e' T' può contenere un numero qualsiasi di 'forall's incorporato. –

+0

@pelotom Ok, scusa per l'equivoco. La domanda che poni è molto più difficile: implica una conoscenza molto complessa dell'algoritmo esatto di controllo del tipo usato dal particolare compilatore a cui sei interessato. Non è possibile passare da una dimostrazione di indecidibilità di un problema a un irrisolvibile istanza di quel problema senza ispezionare l'algoritmo utilizzato per approssimare una soluzione al problema. –

+0

@pelotom Ho aggiunto due sezioni, una sull'altra restrizione importante (predicatività) e una che è un tentativo di rispondere alla tua domanda reale per il caso specifico del controllore del tipo di GHC: dare un termine e un tipo che GHC puo ' al momento verificare. È meglio? –

Problemi correlati