Domanda

Come spiegare il sistema di tipi di Scala a un esperto di Haskell? Quali esempi mostrano i vantaggi di Scala?

Come spiegare il sistema di tipi di Haskell a un praticante di Scala avanzato? Cosa si può fare in Haskell che non si può fare in Scala?

È stato utile?

Soluzione

Scala per un programmatore Haskell:

Scala è un linguaggio rigoroso e impuro con moduli di prima classe. I tipi di dati sono dichiarati come "classi" o "tratti" con sottili differenze, e moduli o "oggetti" sono valori di questi tipi. Scala supporta i costruttori di tipi che accettano parametri di tipo universalmente quantificati. Oggetti / classi / tratti hanno membri costituiti da valori, variabili mutabili e funzioni (chiamati "metodi", a cui il modulo viene implicitamente passato come variabile chiamata this ). I moduli possono avere membri del tipo che possono anche assumere parametri. I membri del tipo sono quantificati esistenzialmente e i parametri del tipo possono essere di tipo più elevato. Poiché i tipi possono essere membri di valori di prima classe, Scala offre un tocco di tipizzazione dipendente chiamato tipi dipendenti dal percorso .

Le funzioni di prima classe sono anche moduli. Una funzione è un modulo con un metodo chiamato apply . Un metodo non è di prima classe, ma viene fornita una sintassi per avvolgere un metodo in una funzione di prima classe. Sfortunatamente, un modulo richiede tutti i suoi parametri di tipo in anticipo, quindi non è possibile quantificare universalmente una funzione di prima classe parzialmente applicata. Più in generale, Scala manca completamente di un meccanismo diretto per i tipi di rango superiore a 1, ma i moduli parametrizzati su tipi di tipo superiore possono essere sfruttati per simulare i tipi di rango-n.

Invece di classi di tipo con ambito globale, Scala consente di dichiarare un valore implicito di un determinato tipo. Ciò include i tipi di funzione, che forniscono una conversione implicita e quindi l'estensione del tipo. Oltre alle conversioni implicite, l'estensione del tipo è fornita da " extends " meccanismo che consente di dichiarare una relazione sottotipo / supertipo tra i moduli. Questo meccanismo può essere utilizzato per simulare tipi di dati algebrici in cui il supertipo può essere visto come il tipo sul lato sinistro di una dichiarazione di dati e i suoi sottotipi come costruttori di valore sul lato destro. Scala ha ampie capacità di corrispondenza dei modelli che utilizzano un modello di corrispondenza virtualizzato con modelli di prima classe.

Scala supporta il sottotipo e questo limita notevolmente l'inferenza del tipo. Ma l'inferenza del tipo è migliorata nel tempo. È supportata l'inferenza di tipi di tipo superiore. Tuttavia, Scala non ha alcun sistema gentile significativo, e quindi non ha alcuna inferenza gentile e nessuna unificazione gentile. Se viene introdotta una variabile di tipo, è di tipo * se non diversamente specificato. Alcuni tipi come Any (il supertipo di tutti i tipi) e Nothing (un sottotipo di ogni tipo) sono tecnicamente di ogni tipo sebbene non possano essere applicato agli argomenti del tipo.

Haskell per un programmatore Scala:

Haskell è un linguaggio puramente funzionale. Ciò significa che le funzioni non possono avere effetti collaterali. Ad esempio, un programma Haskell non stampa sullo schermo in quanto tale, ma è una funzione che restituisce un valore del tipo di dati IO [_] che descrive una sequenza di azioni che il sottosistema IO deve eseguire .

Considerando che Scala è di default rigoroso e fornisce "per nome" annotazione per argomenti di funzione senza restrizioni, Haskell è pigro per impostazione predefinita usando " per necessità " semantica e fornisce annotazioni per argomenti rigorosi.

L'inferenza del tipo in Haskell è più completa che in Scala, con un'inferenza completa. Ciò significa che l'annotazione del tipo non è quasi mai necessaria.

Le recenti estensioni del compilatore GHC consentono funzionalità di sistema di tipo avanzato che non hanno equivalenti in Scala, come tipi di tipo n, famiglie di tipi e polimorfismo dei tipi.

In Haskell, un modulo è una raccolta di tipi e funzioni, ma i moduli non sono entità di prima classe. Gli impliciti sono forniti da classi di tipi, ma questi vengono definiti nell'ambito globale una volta dichiarati e non possono essere passati esplicitamente come in Scala. Più istanze di una classe di tipo per un dato tipo vengono risolte avvolgendo con un newtype per chiarire le ambiguità, mentre in Scala ciò sarebbe risolto semplicemente tramite l'ambito o passando esplicitamente le istanze.

Poiché Haskell non è "orientato agli oggetti", non esiste una dicotomia metodo / funzione. Ogni funzione è di prima classe e ogni funzione è selezionata per impostazione predefinita (nessuna funzione1, funzione2, ecc.)

Haskell non ha alcun meccanismo di sottotipo, ma le classi di tipi possono avere una relazione di sottoclasse.

Altri suggerimenti

Non credo che nessuno abbia sistematicamente confrontato Haskell (come esemplificato dal sistema di tipi di GHC) con Scalas. I principali punti di differenza sono il grado di inferenza del tipo e il supporto per i tipi di livello superiore. Ma un trattamento completo delle differenze sarebbe un risultato pubblicabile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top