2015-12-17 15 views
5

Sto cercando di creare un interprete per un linguaggio funzionale in haskell (sono nuovo nella lingua). Sto creando quello che probabilmente è un mix strano di minimalismo e convenienza - nessun tipo di dati astratti, ma voglio fornire la possibilità di creare liste omogenee.Implementazione di una lingua in Haskell: liste omogenee

Quindi le mie variabili di base sono data Datum = DatInt Int | DatDbl Double | DatBool Bool e mi sono reso conto che non sono affatto sicuro di come rappresentare elenchi omogenei. L'aggiunta di un costruttore List Datum o qualcosa dell'ordinamento renderebbe un elenco eterogeneo e fare un elenco separato per ciascun tipo, ovvero ListInt [Int] | ListDbl [Double] impedirebbe l'elenco di elenchi.

Quale sarebbe il modo migliore per rappresentare un elenco omogeneo?

+4

È possibile utilizzare 'Lista [Datum]' per le liste omogenee, anche se potrebbe in linea di principio contenere quelle eterogenee pure. Se invece vuoi garantire _staticamente_ che tale elenco sia omogeneo, probabilmente avrai bisogno di GADT e possibilmente di tipi esistenziali. Se sei nuovo di Haskell, forse è meglio finire il tuo interprete in un modo più semplice, non statico, per prima cosa. Se ti senti avventuroso, puoi provare a spostarti su un tipo più esperto. – chi

+2

In effetti, il tuo attuale framework non ti offre alcuna possibilità di codificare garanzie di tipo. Se aggiungi un costruttore 'Function', non sarai in grado di assicurarti che le funzioni vengano applicate anche ai tipi giusti. – dfeuer

+0

@chi Desidero fornire garanzie di tipo statico, idealmente senza dover ricorrere a estensioni di lingua. È possibile a tutti? – drowdemon

risposta

5

Una nozione utile (che si tratti di tipi sexy o no) è quella di un tag di tipo. La versione non sexy è molto più facile da gestire.

data Tag = IntTag 
     | DoubleTag 
     | BoolTag 
     | ListTag Tag 
    deriving (Eq, Show) 

Ora i tuoi tipi sono rappresentati da questi vari tag. Un Int è rappresentato da IntTag. Un elenco di Int è rappresentato da ListTag IntTag.

Ora si può rappresentare tipo annotato espressioni qualcosa di simile:

data Expr = IntLit Int 
      | DoubleLit Double 
      | BoolLit Bool 
      | ListLit Tag [Expr] 

-- Check that an expression is validly annotated 
typeCheck :: Expr -> Maybe Tag 
typeCheck IntLit{} = Just IntTag 
... 
typeCheck (ListLit tag els) 
    | all good els = Just (ListTag tag) 
    | otherwise = Nothing 
    where 
    good el = case typeCheck el of 
       Nothing -> False 
       Just res = res == tag 
+2

Per renderlo correttamente estensibile, penso che ci siano due funzioni 'checkType :: Type -> Expr -> Maybe()' e 'inferType :: Expr -> Maybe Type', in modo che' inferType (ListLit tag els) = mapM_ (checkType tag) els >> return (Tag ListTag) 'e' checkType (ListTag t) (ListLit t 'els) = guard (t == t') >> mapM_ (checkType t) els; checkType _ ListLit {} = Nothing' – user2407038

+1

Variante: 'buon el = tipoControllare == Basta taggare'. – chi

Problemi correlati