Ho appena incontrato il "tipo infinito" in Haskell mentre stavo tentando di scrivere una macchina a stati finiti. Ho pensato che il seguente è stato molto intuitivo:Haskell infiniti tipi e la mia funzione FSM
fsm [] _ acc = Right acc
fsm (x:xs) state acc =
case state acc x of
Left err -> Left err
Right (s, a) -> fsm xs s a
rendo la funzione di stato allo stato attuale (l'accumulatore) e il nuovo evento, e la funzione stato produce la funzione stato successivo insieme al nuovo accumulatore. Ricevo fino a quando non ho più eventi.
Il compilatore mi dice:
Occurs check: cannot construct the infinite type:
t1 = b0 -> t0 -> Either a0 (t1, b0)
In the second argument of `fsm', namely `s'
Perché state
è ora un tipo di infinito. Come riorganizzare questo per farlo funzionare?
Grazie. Per me, tutto ciò che fa è dare al tipo infinito un nome, ma il tipo stesso è ancora autoreferenziale. Lo stesso compilatore ha persino chiamato il tipo infinito allo stesso modo. Avrei pensato che il compilatore sarebbe stato in grado di automatizzarlo dandogli un nome. Mi sbaglio? – Ana
@Ana: Mentre è vero che Haskell considera il tuo programma non valido per * scelta * e non per necessità, è per una buona ragione; Non ho alcun collegamento in questo momento, ma * molti * errori comuni su cui ci affidiamo al sistema di tipi da controllare - come mancare un argomento o scrivere un nome di funzione due volte - diventano programmi digitati in modo valido (ma spezzati) se permetti infiniti tipi. – ehird
Nota che non è così semplice come dare un nome al tipo: 'type Infinite = (Bool, Infinite)' è anch'esso vietato; devi racchiuderlo in un * tipo di dati *, che elude tutte le possibilità di errori, perché devi costruire in modo esplicito e abbinare (o utilizzare le funzioni di accesso) su di esso. – ehird