2011-07-22 10 views
17

En Haskell, Iteratee based I/O parece muy atractivo. Los iterados son formas compostables, seguras y rápidas de hacer E/S inspiradas en la función 'fold' a.k.a. 'reducir' en lenguajes funcionales. Básicamente, si tiene un recorrido, la idea es encapsular el estado transversal en el llamado "enumerador" que llama al "iterado", que a su vez es una función que devuelve un valor o una solicitud de más datos junto con una continuación para que el enumerador llame Por lo tanto, solo el enumerador conoce el estado del cruce mientras que el iterado sabe qué hacer con los datos y genera valores a partir de él. Lo bueno de esto es que las iteraciones son compuestas automáticamente, donde la salida de una iteración se alimenta a otra para hacer una más grande.¿iterar E/s tiene sentido en lenguajes no funcionales?

Así, dos preguntas:

  • ¿El concepto aún hacen SENCE en otros idiomas, como lenguajes orientados a objetos simples o es sólo útil para superar las deficiencias de I perezosa de Haskell/S?
  • ¿Existen implementaciones reales para otros lenguajes, especialmente C# (ya que eso es lo que usa mi empresa)? (Una búsqueda en Google hace aparecer una mención de iterar en Scala; bueno, no estoy tan interesado en Scala en este momento).
+0

¿No es eso básicamente para lo que está diseñado el nuevo material asíncrono en C# 5.0? El mecanismo es diferente, pero la implementación subyacente es básicamente una de continuación. –

+0

Gracias por señalar eso. Aún no lo sabía, y ciertamente parece emocionante, así que tengo que analizarlo, aunque no puedo ver mucho que tenga en común con las iteraciones. ;-) – firefrorefiddle

Respuesta

8
+0

Por lo que puedo ver a primera vista, ¡creo que tienes razón! Gracias, los investigaré. – firefrorefiddle

+0

No es mi implementación finalizada. Muestra estructura básica. https://gist.github.com/4025522. Existe una diferencia entre Observer no puede enviar mensajes a observable (solo Darse de baja a través de IDisposable) pero iteratee puede enviar mensajes al enumerador. –

8

En primer lugar, tenga en cuenta que "Lazy IO" de Haskell es una especie de hack que rompe la pureza de forma limitada para permitir la entrada y salida de E/S ya que los datos se consumen perezosamente. Esto es normal en un lenguaje impuro, y las secuencias perezosas pueden crear el mismo problema en cualquier lugar. Por lo tanto, si está haciendo algo como, por ejemplo, exponer una interfaz IEnumerable a un archivo y leerla gradualmente a medida que se enumera la secuencia, esto no es realmente diferente.

En segundo lugar, iteratees y enumeradores también se pueden componer en lo que se denominan (de manera algo torpe) enumeratees. En este punto, tiene algo alimentado con datos secuenciales, que produce resultados incrementales cuando están listos y alimenta esos resultados a otra cosa. Esto es básicamente una variedad de procesador de flujo, un concepto que probablemente es anterior tanto a Haskell como a C# por un margen considerable.

En tercer lugar, iteratees son una encapsulación de comportamiento abstraído, con sus funciones internas ocultas. Esto es posiblemente más acorde con los principios OO que con la programación funcional al estilo ML, al menos en el sentido de "principios OO" que defienden las personas que le gritan por usar getters y setters y piensan que el flujo de control debería implementarse a través de polimorfismo.

Dado lo anterior, diría que el concepto iteratee cabría perfectamente en C#, y se implementaría más naturalmente como una especie de equivalente invertido de IEnumerable, con objetos de flujo de datos compositivos y una interfaz "push" en lugar del estilo "pull" de LINQ estándar.

+0

¡Gracias por la gran explicación! – firefrorefiddle

+0

@Mike Hartl: Y por lo que vale, me había olvidado de las extensiones reactivas; después de echar un vistazo al enlace que Charles dio, es bastante claro en la misma línea que lo que describo. –

Cuestiones relacionadas