Il problema con n+k
modelli risale a una decisione di progettazione in Haskell, di distinguere tra i costruttori e le variabili nei modelli dal primo carattere dei loro nomi. Se si torna a ML, una definizione di funzione comune potrebbe essere simile (utilizzando la sintassi Haskell)
map f nil = nil
map f (x:xn) = f x : map f xn
Come si può vedere, sintatticamente non c'è alcuna differenza tra f
e nil
sul lato sinistro della prima linea, ma hanno ruoli diversi; f
è una variabile che deve essere associata al primo argomento a map
mentre nil
è un costruttore che deve essere confrontato con il secondo. Ora, ML fa questa distinzione osservando ogni variabile nell'ambito circostante e assumendo che i nomi siano variabili quando la ricerca fallisce. Pertanto, nil
viene riconosciuto come costruttore quando la ricerca non riesce. Ma si consideri cosa succede quando c'è un errore di battitura nel modello:
map f niil = nil
(due i
s in niil
). niil
non è un nome costruttore in ambito, quindi viene trattato come una variabile e la definizione viene interpretata in modo non corretto in modo errato.
La soluzione di Haskell a questo problema è di richiedere che i nomi dei costruttori inizino con lettere maiuscole ei nomi delle variabili iniziano con lettere minuscole. E, per gli operatori/costruttori infissi, i nomi dei costruttori devono iniziare con :
mentre i nomi degli operatori potrebbero non iniziare con :
.Questo aiuta anche a distinguere tra attacchi decostruendo:
x:xn = ...
è chiaramente un legame decostruire, perché non si può definire una funzione denominata :
, mentre
n - m = ...
è chiaramente una definizione di funzione, perché -
puo' essere un nome costruttore
Tuttavia, i modelli n+k
, come n+1
, indicano che +
è sia un nome di funzione valido, sia qualcosa che funziona come un costruttore nei modelli. Ora
n + 1 = ...
è di nuovo ambiguo; potrebbe essere parte della definizione di una funzione denominata (+)
oppure potrebbe essere una decostruzione della definizione della corrispondenza del modello di n
. In Haskell 98, questa ambiguità è stato risolto dichiarando
n + 1 = ...
definizione di una funzione, e
(n + 1) = ...
un Deconstructing vincolante. Ma ovviamente non è mai stata una soluzione soddisfacente.
Anche se penso che i modelli 'n + k' abbiano un certo fascino, _convertendo_ tra una rappresentazione basata su 1 e zero, IMO non sarebbe mai stato un caso d'uso appropriato. Dovevano "decostruire" i numeri in modo ricorsivo. - FWIW, 'insertAt' dovrebbe essere a zero comunque, non dovrebbe? – leftaroundabout
@leftaroundabout, 'insertAt' dovrebbe essere basato su 1 in base all'esempio fornito:' insertAt 'X' "abcd" 2' -> '" aXbcd "'. – Mark
Sì, intendevo, dovrebbe essere _specified_ in modo che sia basato su 0, poiché tutte le funzioni dell'elenco standard di Haskell sono ([giustamente] (https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831 .html)). – leftaroundabout