Actualmente estoy escribiendo un analizador de expresiones. He hecho el análisis léxico y sintáctico y ahora estoy verificando los tipos. Tengo la expresión en un structire de datos como esta (versión simplificada):¿Cómo crear una función Haskell que introduzca un nuevo tipo?
data Expr = EBinaryOp String Expr Expr
| EInt Int
| EFloat Float
Y ahora necesito una función que convertir esto en un nuevo tipo, responda TypedExpr
, que también contendría información de tipo. Y ahora mi principal problema es cómo debería verse este tipo. Tengo dos ideas - con parámetro de tipo:
data TypedExpr t = TEBinaryOp (TBinaryOp a b t) (TExpr a) (TExpr b)
| TEConstant t
addTypes :: (ExprType t) => Expr -> TypedExpr t
o sin:
data TypedExpr = TEBinaryOp Type BinaryOp TypedExpr TypedExpr
| TEConstant Type Dynamic
addTypes :: Expr -> TypedExpr
empecé con la primera opción, pero me encontré con problemas, ya que este enfoque supone que sabe tipo de la expresión antes de analizarlo (para mí, es cierto en la mayoría de los casos, pero no siempre). Sin embargo, me gusta, porque me permite usar el sistema de tipos de Haskell y verificar la mayoría de los errores en tiempo de compilación.
¿Es posible hacerlo con la primera opción?
¿Cuál elegirías? ¿Por qué?
¿Qué problemas debo esperar con cada opción?
¡Guau! idea interesante. Nunca lo pensaría :) – mik01aj
Creo que no entiendo muy bien tu solución: ¿qué se supone que 'eInt', 'eBinaryOp' tiene que hacer? ¿Dónde coloco mi 'Expr' en este modelo? – mik01aj