Ci sono alcuni modi per procedere digitando questo.
Dimentica tutti i tipi!
Puoi imitare i tipi dinamici in linguaggi tipizzati in modo statico semplicemente dimenticando che avevi tipi in primo luogo e passando a utilizzare le informazioni sul tipo di runtime.
In haskell questo sarebbe simile a
evalThingy s = let result = eval s
resultTy = typeOf result
if resultTy == typeOf (id :: String -> String)
then unsafeCoerce result s
else fail in some manner
Quindi abbiamo un interruttore di runtime che controlla solo se è sicuro continuare e se lo è, battere il tipografo in sottomissione e procedere.
Personalmente non mi piace in questo modo, perché se dovessi scrivere qualcosa in un sistema di tipo statico, voglio ottenere i benefici per la sicurezza. Ciò significa che le coercizioni come sopra sono un no-no.
Errore esplicito
Il più semplice è forzare eval
a restituire un tipo specifico o fallire in modo controllato
eval : String -> Either Error a
E quindi potremmo dire qualcosa di simile
c = eval(str) : Either Error (str -> Int)
case c of
Right f -> f str
Left err -> blowup str
Per supportare questo bene, il linguaggio ha bisogno di qualcosa chiamato polimorfismo di tipo [parametrico] di ritorno. ATM Sono consapevole solo del fatto che sia supportato dalle classi di tipi. Ciò significa che abbiamo bisogno di cose diverse a seconda di come è chiamato il tipo.
Tipi di dipendenti
L'approccio più contorto sarebbe quello di riflettere effettivamente il giudizio di battitura della lingua in una funzione, diciamo typeOf
.
typeOf : String -> TypeOfTypes
Dove TypeOfTypes
è l'universo di tutti i tipi che i programmi normalmente usano. Questo non può includere se stesso se vogliamo un po 'di sanità mentale nel nostro sistema di tipi.
Successivamente possiamo assegnare eval
un tipo dipendente abbastanza complesso a eval
eval : (s : str) -> typeOf str
applySelf : (s : String) -> typeOf s = (String -> String) -> String
applySelf = function(s, p){
case p of
reflexivity -> eval(s)(s)
}
Quindi forziamo il chiamante di applySelf
a dimostrare che la stringa che ci chiedono di valutare avrà il tipo string -> string
a quel punto possiamo ignorare i controlli di sicurezza poiché abbiamo una prova di correttezza statica.