2015-12-15 17 views
22

Haskell è fortemente digitato? Cioè è possibile cambiare il tipo di una variabile dopo averne assegnata una? Non riesco a trovare la risposta su Internet.Haskell è un linguaggio di programmazione fortemente tipizzato?

+8

Se Haskell è fortemente digitato dipende dal tipo di sistema o meno. Vedi http://ericlippert.com/2012/10/15/is-ca-strongly-typed-or-a-weakly-typed-language/ –

+7

["Strongly typed" e "weakly-typed" sono mal definiti. ] (http://programmers.stackexchange.com/a/38257/102349) Probabilmente vorrai chiedere se Haskell è digitato dinamicamente (no, non lo è). –

+10

Nota che in Haskell non puoi nemmeno cambiare il * valore * di una variabile dopo che è stata assegnata; quindi, anche se Haskell fosse stato digitato dinamicamente, il tipo di runtime di una variabile sarebbe stato corretto all'assegnazione. – ruakh

risposta

75

Statico - i tipi sono noti al momento della compilazione. Java e Haskell sono tipizzati staticamente.

Una lingua tipizzata in modo statico può avere o meno un'inferenza di tipo. Java quasi completamente manca di inferenza di tipo (ma sta cambiando molto lentamente un po '); Haskell ha l'inferenza di tipo completo (tranne con alcune estensioni molto avanzate).

Dinamico - Python, Ruby, ecc. Alcuni lo chiamano "unityped"; la dinamica può essere "emulata" all'interno di un'impostazione statica, ma il contrario non è vero a meno che non si aggiungano strumenti/plug-in di analisi statica esterni a un linguaggio tipicamente scritto in modo dinamico. Alcune lingue si mescolano dinamiche e statiche.

Forte - i valori che devono essere trattati come Cat sono sempre; provare a trattarli come un Dog causerà un forte meeewww ... Voglio dire errore.

Debole - questo si riduce in modo efficace fino a 2 cose simili, ma distinti: la coercizione di tipo (per esempio "5"+3 uguale 8 in PHP - o lo fa!) E la memoria reinterpretazione (per esempio(int) someCharValue o (bool) somePtr in C e anche in C++, ma il C++ vuole che tu dica esplicitamente reinterpret_cast). Quindi c'è davvero coercizione-debole e reinterpretazione-debole e lingue diverse sono deboli in uno o entrambi questi modi. È interessante notare che la coercizione è implicita per natura e la reinterpretazione della memoria è esplicita (eccetto in Assembly), quindi la digitazione debole consiste in un comportamento implicito e. Forse è ancora più un motivo per fare riferimento a 2 sottocategorie distinte sotto una digitazione debole.


Esistono lingue con tutte le 4 possibili combinazioni e varianti/gradazioni.

Haskell è statico + forte; ovviamente ha unsafeCoerce quindi può essere statico + un po 'reinterpretato-debole a volte, ma unsafeCoerce è molto disapprovato tranne in situazioni estreme in cui sei sicuro di qualcosa che sia il caso ma non riesco a convincere il compilatore senza tornare indietro e raccontare l'intera storia in un modo diverso.

C è statico + debole perché tutta la memoria può essere reinterpretata liberamente come qualcosa che originariamente non era destinata a contenere, quindi debole. Ma tutte queste reinterpretazioni sono tenute sotto controllo dal controllore del tipo, quindi anche completamente statico. Ma C non fa coercizione implicita, quindi è solo reinterpret-weak.

Python è dinamico + quasi interamente forte - non esistono tipi noti in un dato riga di codice prima di raggiungere quella linea durante l'esecuzione, comunque valori che vivono in fase di esecuzione associ tipi associati con loro ed è impossibile reinterpretare memoria. Anche le coercizioni implicite sono ridotte al minimo, quindi si potrebbe dire che Python sia forte del 99,9% e 0,01% coercizione-debole.

PHP e JavaScript sono dinamici + per lo più debole - dinamica, nel senso che nulla è digitare fino a quando si esegue e introspezione il suo contenuto, ma anche debole che coercizioni capita tutto il tempo e con le cose che non avevo mai realmente si aspettano di essere forzato, a meno che non si stiano chiamando metodi e funzioni e non si utilizzino le operazioni integrate. Queste coercizioni sono una fonte di molto umorismo su Internet. Non ci sono reinterpretazioni di memoria, quindi PHP e JS sono coercizione-debole.


Inoltre, alcune persone piace pensare che tipizzazione statica è sulle variabili che hanno il tipo e la tipizzazione forte è sui valori che hanno tipo - questo è un modo molto utile per andare a capire il quadro completo, ma non è piuttosto vero: alcuni linguaggi tipizzati dinamicamente consentono anche di annotare variabili/parametri con tipi/vincoli che vengono applicati in fase di esecuzione.

Nella tipizzazione statica, sono espressioni che hanno un tipo; il fatto che le variabili siano di tipo è solo una conseguenza delle variabili utilizzate come mezzo per incollare espressioni più grandi insieme da quelle più piccole, quindi non sono le variabili di per sé che hanno tipi.

Analogamente, nella digitazione dinamica, non sono le variabili che mancano di tipo staticamente conosciuto - sono tutte espressioni! Le variabili prive di tipo sono semplicemente una conseguenza delle espressioni che conservano senza tipo.


Un esempio finale

In tipizzazione dinamica, tutti i gatti, cani e persino gli elefanti (di fatto interi zoo!) Sono confezionati in scatole identiche dimensioni.

Nella digitazione statica queste scatole hanno un aspetto diverso e hanno adesivi su di loro che dicono cosa c'è dentro.

Ad alcune persone piace perché possono semplicemente utilizzare un fattore di forma a scatola singola e non devono mettere alcuna etichetta sulle scatole - è solo la disposizione delle scatole l'una rispetto all'altra che implicitamente (e si spera) fornisce tipo sanità mentale.

A qualcuno piace anche perché permette loro di fare tutti i tipi di trucchi con tigri temporaneamente trasportati in scatole che odorano di leoni, e gli orsi mettono nella stessa serie di scatole interconnesse come lupi o cervi.

In tali impostazioni di scatole di trasporto prive di etichette, tutti i possibili scenari logistici devono essere riprodotti o simulati al fine di rilevare il disallineamento nell'accordo implicito, come in una prestazione sul palco. Nessuna garanzia affidabile può essere data solo in base al ragionamento, in generale. (casi di test ad hoc che richiedono l'avvio dell'intero sistema per ottenere conclusioni parziali della sua solidità)

Con etichette e regole esplicite su come gestire scatole di varie etichette, automatizzato/meccanizzato logico il ragionamento può essere utilizzato per trarre conclusioni su ciò che il sistema logistico non farà o sicuramente farà (verifica statica, prova formale o almeno pseudo-prova come QuickCheck), alcuni aspetti della logistica devono ancora essere verificati con corse di prova, ad esempio se il team logistico ha persino ottenuto il diritto del cliente. (test di integrazione, test di accettazione, controlli di integrità dell'utente finale).


Inoltre, in cani a digitazione deboli possono essere tagliati e riassemblati come gatti frankenstein. Che gli piaccia o no, e se il risultato sia brutto o no. (digitazione debole)

Ma se si aggiungono etichette alle scatole, è ancora importante che i gatti di Frankenstein siano messi in scatole di gatti. (Statico + tipizzazione debole)


In tipizzazione forte, mentre si può mettere un gatto nella scatola di un cane, ma si può tenere solo facendo finta che un cane fino a quando si tenta di umiliarla alimentando solo qualcosa i cani mangiano - se ciò accade, urlerà ad alta voce, ma fino a quel momento, se si sta digitando dinamicamente, si accetterà silenziosamente il suo posto (in un mondo statico si rifiuterà di essere messo in una scatola di cani prima di te posso dire "gattina").

+0

Non direi che è impossibile reinterpretare la memoria, ci sono un paio di progetti che implementano gli assemblatori in Python riempiendo una matrice numpy con le istruzioni quindi puntando i ctype nella posizione di memoria e chiamandoli una funzione, ed è in realtà tecnicamente possibile scambiare il tipo di un oggetto, ma entrambi questi esempi colpiscono angoli profondi e oscuri di Python che probabilmente i mortali non dovrebbero neanche sapere. – bheklilr

+0

Le variabili hanno tipi diversi dalle espressioni. Una definizione di funzione in Haskell avrà parametri (variabili) che non sono legati alle espressioni ma che certamente hanno tipi. Nel sistema F e nei suoi parenti, le variabili (ma non le espressioni) devono essere annotate esplicitamente con i tipi. – dfeuer

+0

Gli argomenti di funzione sono nomi per le espressioni che saranno "posizionate in esse" - questo è ciò che intendevo concettualmente; Non ho preteso di essere tipo teoricamente corretto nella terminologia :) –

0

Penso che tu stia parlando di due cose diverse.

In primo luogo, haskell e la maggior parte dei linguaggi di programmazione funzionale (FP), NON hanno il concetto "variabile". Invece, usano il concetto "nome" e "valore", semplicemente "legano" un valore a un nome. Una volta che il valore è vincolato, non è possibile associare un altro valore allo stesso nome, questa è la caratteristica chiave di FP.

La tipizzazione forte è un altro argomento. Sì, haskell è fortemente digitato, così come la maggior parte dei linguaggi FP. Una forte digitazione dà a FP la capacità di "inferenza del tipo" che è potente per eliminare bug nascosti in fase di compilazione e aiuta a ridurre le dimensioni del codice sorgente.

Forse stai confrontando haskell con python? Python è anche fortemente digitato. La differenza tra haskell e python è "static typed" e "dynamic typed". Il vero significato del termine "Tipo forte" e "Tipo debole" sono ambigui e sfocati. Questa è un'altra lunga storia ...

+0

Ah, vedo la differenza ora. Grazie! –

+3

scusate ma state mescolando forte e statico, oltre a fare riferimento a "type checking" ma parlando di "type inferenza", invece: _Strong typing dà a FP la capacità di "type inferenza" che è potente per eliminare bug nascosti in fase di compilazione e aiuta a ridurre la dimensione del codice sorgente. –

+3

Noi * facciamo * abbiamo il concetto di una variabile; usiamo la parola un po 'diversamente. Una variabile in un linguaggio funzionale è molto simile a una * variabile * matematica. – dfeuer

7

Sembra che si confondano la digitazione dinamica/statica e debole/forte.

La digitazione dinamica o statica indica se il tipo di variabile può essere modificato durante l'esecuzione.

La digitazione debole o forte riguarda la possibilità di prevedere errori di tipo solo dalle firme delle funzioni.

Haskell è sia statico che fortemente digitato.

Tuttavia, non vi è alcuna variabile come in Haskell, quindi parlare di digitazione dinamica o statica non ha senso poiché ogni identificatore assegnato con un valore non può essere modificato all'esecuzione.

EDIT: Ma come diceva goldenbull, quelle nozioni di battitura non sono chiaramente definite.

+1

La tipizzazione forte da sola non consente di prevedere qualsiasi cosa; fa in modo che i gatti non finiscano per essere trattati come cani (pensate quanto sarebbe terribile per il gatto ...). Solo statico combinato con forti lo fornisce; ma di nuovo anche statico + debole offre molta prevedibilità. –

Problemi correlati