E/S recursiva de Haskell

Tengo algunos problemas al tratar de incorporar una declaración de lectura y escritura en evaluateStatementInner función.

Intenté cambiar los tipos de devolución de ambas funciones sin éxito.

Estoy tratando de convertir un tipo IO(Env) dentro Env. Sé que esto se puede hacer con enlace en una función que devuelve un IO acción pero puedo hacerlo en el evaluateInner ¿declaración?

¡Salud

preguntado el 12 de junio de 12 a las 12:06

No enlace a un código externo, extraiga solo lo que se necesita para comprender y responder y póngalo en su pregunta. Tendrás muchas más posibilidades de obtener ayuda ;) -

Supongo que no puedes hacer Pure function calling Impure (IO) function mientras que lo contrario es cierto. -

No estoy realmente seguro de cómo llamar a la lectura dentro de la función interna. -

¿Puedes explicar por qué necesitas tenerlos en evaluateStatementInner? (es decir, ¿por qué tenerlos en evaluateStatement no es lo suficientemente bueno?) -

También pensé en eso, pero evaluarStatementInner trata con una o más declaraciones que devuelven un Env mientras que EvaluationStatement devuelve IO(Env). No pude compilarlo ya que cuando uso la recursividad ya que la función devuelve IO (Env) mientras necesito Env. -

1 Respuestas

Evaluación Read y Write necesariamente implica realizar i/o. Así que muerde la bala y cambia el tipo de evaluateStatementInner a Stmt -> Env -> IO Env (o, mejor, incorporarlo directamente a evaluateStatement).

A continuación, tendrá que modificar evaluateListOfStatements ser de tipo [Stmt] -> Env -> IO Env.


Entonces esto ahora te da un error de compilación

case stmt of
...
    While boolExp innerStmt ->
        if evaluateBoolExp boolExp env
            then evaluateStatementInner (While boolExp innerStmt) (evaluateStatementInner innerStmt env)
            else env

porque evaluateStatementInner innerStmt env produce un IO Env, pero evaluateStatementInner (While boolExp innerStmt) quiere un Env.

Este es un caso de enlace monádico (y tenga en cuenta que la rama else necesita actualizarse para tener el tipo correcto también):

case stmt of
...
    While boolExp innerStmt ->
        if evaluateBoolExp boolExp env
            then evaluateStatementInner (While boolExp innerStmt) =<< evaluateStatementInner innerStmt env
            else return env

Es posible que no se sienta cómodo con los operadores monádicos, así que lo traduciré a la notación do:

case stmt of
...
    While boolExp innerStmt ->
        if evaluateBoolExp boolExp env
            then do env' <- evaluateStatementInner innerStmt env
                    evaluateStatementInner (While boolExp innerStmt) env'
            else return env

Respondido el 12 de junio de 12 a las 15:06

Intenté esto pero aparece un error de compilación en esta línea: "luego evaluarStatementInner (While boolExp innerStmt) (evaluateStatementInner innerStmt env)" donde dice el tipo esperado Env pero el tipo real es IO(Env). A eso me referia en el otro comentario. - user1424720

Gracias funcionó. Tal vez debería haberme metido un poco más en Haskell antes de comenzar este proyecto. Una vez que termino, leo sobre los operadores monádicos. - user1424720

El Typeclassopedia tiene una buena sección sobre mónadas y explica los operadores monádicos en contexto (pero lea primero las secciones anteriores). - dave4420

Le echaré un vistazo. Hasta ahora solo he leído los primeros capítulos de Real World Haskell. - user1424720

@user1424720, deberías leer más capítulos :) (y tal vez te guste Aprende un Haskell como un tutorial desde una perspectiva ligeramente diferente.) - huón

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.