2011-09-02 11 views

Respuesta

5

Puede convertir cualquier algoritmo que use estado mutable en un algoritmo que "encadena" el estado junto con él. Haskell proporciona una forma de hacerlo tal que todavía se siente como una programación imperativa con el estado Monad.

Aunque, me parece que la operación básica de blit podría hacerse en un estilo más funcional. Básicamente está combinando dos mapas de bits para producir un nuevo mapa de bits mediante el funcionamiento de píxel por píxel. Eso suena muy funcional para mí.

alta calidad del código imperativo es a menudo más rápido que un buen código funcionales, pero si usted está dispuesto a renunciar a un poco de velocidad que normalmente puede crear muy buenos arquitecturas con un estilo funcional pura

4

Haskell tiene efectos secundarios y que debería usarlos cuando sea apropiado. Una rutina blit de alta velocidad que va a estar en su bucle interno (y por lo tanto es crítica para el rendimiento) es ciertamente un lugar donde la mutación es apropiada, ¡así que úsala! Tiene un par de opciones:

  • Haga rodar el suyo en Haskell, usando ST (U) Array o IO (U) Array. No recomendado.
  • Haga rodar el suyo en C y llámelo con el FFI. No recomendado.
  • Utilice uno de los muchos kits de herramientas gráficas que ya ofrecen este tipo de operaciones, y tiene cientos de horas dedicadas al programador para hacer una buena interfaz con alto rendimiento, como Gtk u OpenGL. Muy recomendable.

¡Disfrútalo!

1

una manera funcional natural de representación de una imagen es el uso de la función de índice:

Image :: (Int,Int) -> Color 

Con esta representación, blitting un área de una imagen a otra que se lograría con

blit area a b = \(x,y) -> if (x,y) `isInsideOf` area then a (x,y) else b (x,y) 

Si Se requiere traducción u otra transformación, se puede aplicar directamente a las coordenadas:

translate (dx,dy) image = \(x,y) -> b (x+dx,y+dy) 

Esta representación le proporciona una forma natural de trabajar con puntos de imagen. Puede, por ejemplo, trabajar fácilmente con las áreas no rectangulares, y hacer trucos como hacer la interpolación de imagen como función independiente en lugar de ser parte de sus algoritmos de imagen de escala habituales:

quadraticInterpolation :: ((Int,Int) -> Color) -> ((Double,Double) -> Color) 

El rendimiento puede sufrir en algunos casos, como cuando se combinan varias imágenes en una y luego se hacen cálculos con el resultado. Esto da como resultado una cadena de pruebas para cada píxel para cada cálculo sucesivo. Sin embargo, al aplicar la memorización, podemos representar temporalmente la representación funcional en una matriz y transformarla en función de índice, eliminando así el rendimiento alcanzado por las operaciones sucesivas.

Tenga en cuenta que la memorización también se puede utilizar para introducir el paralelismo en el proceso.

Cuestiones relacionadas