Pregunta

No estoy seguro exactamente cuánto de esto cae bajo la 'programación' opuesto a 'el programa de lenguaje de diseño'.Pero la cuestión es esta:

Decir, en aras de la simplicidad tenemos dos 'especial' listas/matrices/vectores/lo que sea, simplemente llamamos 'puertos' por simplicidad, uno llamado stdIn y otro stdOut.Estos conceptualmente representan respectivamente

  • Todas las entradas de usuario dado que el programa en el periodo de duración del programa
  • Toda la salida por escrito a la terminal durante la duración del programa

En Haskell inspirado en pseudocódigo, entonces debería ser posible crear esta totalmente declarativa programa:

 let stdOut =   ["please input a number", 
                "and please input another number", 
                "The product of both numbers is: " ++ stdIn[0] * stdIn[1]]

Que haría lo esperado, pida dos números, y la impresión de su producto.El truco está en que stdOut representa la lista de cadenas de caracteres escritos a la terminal, en la realización del programa, y stdIn la lista de las cadenas de entrada.Los errores de tipo y el hecho de que se necesita un poco de protección para imprimir sólo la línea siguiente después de una nueva línea ha sido introducido a la izquierda a un lado aquí para simplificar, es probablemente bastante fácil de resolver.

Por tanto, antes de ir a la implementación de esta idea, hay trampas que he pasado por alto?No soy consciente de similar construcción ya existente, por lo que sería ingenuo como para no tomar en cuenta que existe un evidente peligro de esto, me he pasado por alto.

De lo contrario, yo sé que de curso:

 let stdOut =   [stdIn[50],"Hello, World!"]

Sería un error si estos resultados deben ser entrelazados en una manera similar como en el anterior.

¿Fue útil?

Solución

Un enfoque similar fue utilizado en las primeras versiones de Haskell, excepto que los elementos de la stdin y stdout canales no eran cadenas, pero genérico IO 'acciones'--de hecho, la entrada y la salida fueron generalizadas a la 'respuesta' y 'pedir'.Mientras tanto los canales son perezosos (es decir,son realmente "iteradores' o 'los enumeradores'), el tiempo de ejecución puede simplemente caminar por la solicitud de canal, actuar en cada solicitud y de la tachuela respuestas apropiadas en el canal de respuesta.Por desgracia, el sistema era muy difícil de usar, por lo que fue desechado en favor de monádico IO.Ver estos papeles:

  • Hudak, P., y Sundaresh, R.En la expresividad de los puramente funcional I/O sistemas.Tech.El representante.YALEU/DCS/RR-665, del Departamento de Ciencias de la computación, de la Universidad de Yale, Mar.1989.
  • Peyton Jones, S.Lucha contra la Torpe Escuadrón:monádico de entrada/salida, la simultaneidad, excepciones, y en lengua extranjera llamadas en Haskell.En la Ingeniería de las teorías de la construcción de software, 2002, pp.47--96.

Otros consejos

El enfoque que describes suena como "cuadros de diálogo." En su galardonado documento de 1993 Imperativa Programación Funcional, Phil Wadler y Simon Peyton Jones dar algunos ejemplos donde los diálogos realmente no funcionan muy bien, y que explique por qué monádico de e/S es mejor.

No veo cómo se tejen a ellos teniendo en cuenta este ejemplo, en comparación con su propio:

let stdOut =   ["Welcome to the program which multiplies.",
                "please input a number", 
                "and please input another number", 
                "The product of both numbers is: " ++ stdIn[0] * stdIn[1]]

Si el programa solicitará el número representado por la stdIn[0] después de la salida de una línea (como en tu ejemplo) o dos líneas?Si el índice de 0 representa el 0 de entrada de stdin, entonces parece algo similar a:

let stdOut =   ["Welcome to the program which multiplies.",
                "please input a number",
                some_annotation(stdIn[0]),
                "and please input another number", 
                some_annotation(stdIn[1]),
                "The product of both numbers is: " ++ stdIn[0] * stdIn[1]]

será necesario, a fin de coordinar el calendario de salida y de entrada.

Me gusta tu idea.Reemplazar some_annotation con su preferencia, tal vez algo parecido "sincronizar?" Yo no podía llegar con el incisivo palabra.

Este enfoque parece ser el "más evidente" de añadir e/S a una pura λ-cálculo, y otras personas han mencionado que algo a lo largo de esas líneas que se ha tratado en Haskell y Miranda.

Sin embargo, soy consciente de una lengua, no se basa en un λ-cálculo, que todavía se utiliza un sistema similar:

Cómo controlar la entrada y salida en un lenguaje sin efectos secundarios?En un cierto sentido, de entrada y de salida no efectos secundarios;son, por así decirlo, frontal y posterior de los efectos.(...) [Un programa es] una función desde el espacio de las posibles entradas para el espacio de posibles salidas.

Secuencias de entrada y salida son representado como una lista de naturales los números de 0 a 255, cada correspondiente a un byte.Fin-de-archivo está representado por el valor de 256, no al final de la lista.(Esto es porque es a menudo es más fácil lidiar con la EF como un personaje que como un caso especial.Sin embargo, me pregunto si no ser mejor uso final de la lista.)

(...)

No es difícil escribir los programas interactivos (...) [pero] haciendo así es, técnicamente hablando, un pecado.(...) En una referentially transparente el lenguaje, cualquier cosa que no sea explícitamente sincronizado es un juego justo para la evaluación en cualquier orden que sea, en el sistema de tiempo de ejecución de la discreción.

(...) La forma más obvia de la escritura este programa en particular es contras junto con el "Hola, [nombre]!" cadena en una expresión que está condicionada en la recepción de una nueva línea.Si usted esto es seguro, porque no hay ninguna manera para que cualquier evaluador para probar en antemano que el usuario nunca escriba una newline.

(...)

Así que no hay problema práctico con software interactivo.Sin embargo, hay algo desagradable acerca de la el segundo caso es prevenir.Un referentially transparente programa no debería tener que depender de perezoso evaluación con el fin de funcionar correctamente.

Cómo escapar de este dilema moral?El el camino difícil es cambiar a una más sofisticado sistema de I/O, tal vez basado en Haskell, en la que la entrada y la de salida son explícitamente sincronizado.Soy bastante reacio a hacerlo, como Me gusta mucho la sencillez de la sistema actual.El camino fácil es escribir programas por lotes que suceden a los funcionan bien de forma interactiva.Este es principalmente sólo una cuestión de no preguntar el usuario.

Tal vez usted podría disfrutar haciendo algo de programación en Lazy K?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top