2009-12-14 7 views
8

Vorrei capire qual è la differenza tra questi due concetti di programmazione. Il primo rappresenta l'assenza del tipo di dati e al secondo il tipo esiste ma non ci sono informazioni. Inoltre, riconosco che l'Unità deriva dalla base teorica della programmazione funzionale, ma non riesco ancora a capire quale sia l'usabilità dell'unità primitiva (ad esempio, in un programma F #).Vuoto in contrasto con l'unità

risposta

11

Il tipo di unità rende tutto più regolare. In una certa misura puoi pensare ad ogni funzione in F # come prendere un singolo parametro e restituire un singolo risultato. Le funzioni che non richiedono alcun parametro effettivamente prendono come parametro "unità" e le funzioni che non restituiscono alcun risultato restituiscono "unità" come risultato. Questo ha una varietà di vantaggi; per uno, considera come in C# hai bisogno sia di un gran numero di delegati "Func" per rappresentare le funzioni di varie entità che restituiscono valori, sia di un gran numero di delegati "Azione" che non restituiscono valori (perché ad esempio Func<int,void> non è legale - il vuoto non può essere usato in questo modo, poiché non è un tipo abbastanza "reale").

Vedi anche F# function types: fun with tuples and currying

+0

Ben spiegato +1 – Dario

+0

E() è solo la fine logica delle tuple di n-ary, una tupla di elementi 0! – Dario

+0

Grazie! Segnato. –

8

Nella programmazione funzionale, di solito parliamo di input di mappatura alle uscite. Questo significa letteralmente mappare un argomento al suo valore restituito. Ma se qualcosa sta per essere una funzione nel senso di teoria matematica/categoria, deve restituire qualcosa. Un valore void rappresenta che una funzione non restituisce nulla, che è priva di senso in questi termini.

unit è la risposta funzionale a void. È essenzialmente un tipo con un solo valore, (). Ha un numero di usi, ma qui è semplice. Diciamo che hai avuto qualcosa di simile in un linguaggio più tradizionale imperativo:

public static <T, U> List<U> map(List<T> in, Function<T, U> func) { 
    List<U> out = new ArrayList<U>(in.size()); 
    for (T t : in) { 
    out.add(func.apply(t)); 
    } 
    return out; 
} 

Ciò vale una particolare funzione func ad ogni elemento della lista, producendo un nuovo elenco di tipo di uscita func s'. Ma cosa succede se passi in una Funzione che stampa solo i suoi argomenti? Non avrà un tipo di output, quindi cosa puoi mettere per U?

In alcune lingue, il passaggio di una funzione di questo tipo interromperà questo codice (come in C#, dove non è possibile assegnare void a un tipo generico). Dovresti ricorrere a soluzioni alternative come avere un Action<T>, che può diventare goffo.

Questo è dove il concetto di unit è utile: esso è un tipo, ma che può assumere solo un singolo valore. Ciò semplifica enormemente le cose come il concatenamento e la composizione e riduce enormemente il numero di casi speciali di cui ti devi preoccupare.

+0

+1 per questa risposta troppo. Il tuo frammento è stato abbastanza completo. Grazie! –