2012-01-27 22 views
9

¿Puede alguien explicar o dar algunos recursos sobre cómo funciona la composición funcional en relación con la pereza?pereza y composición de la función (haskell, erlang)

Por ejemplo, ¿cómo funciona filter (/='W') . map toUpper $ "justaword" en Haskell en comparación con su contraparte en erlang que no es flojo?

Respuesta

13

Cada vez que se solicita otro carácter (o notificación de finalización), el siguiente carácter - si hay alguno - se mapea a mayúsculas, que se compara con 'W', entregado si es desigual.

filter (/= 'W') . map toUpper $ "justaword" 
~> filter (/= 'W') (toUpper 'j' : map toUpper "ustaword") 
~> filter (/= 'W') ('J' : map toUpper "ustaword") 
~> 'J' : filter (/= 'W') (map toUpper "ustaword") 

Ahora el primer carácter está disponible, por lo que para consultas como null o funciones como take 1, sin más trabajo está hecho. Si el consumidor demanda más caracteres, se producirán uno por uno hasta que se llegue al final de la cadena.

Ejemplo:

Prelude Data.Char> take 10 . filter (/= 'W') . map toUpper $ repeat 't' 
"TTTTTTTTTT" 

repeat produce una lista infinita, pero siempre y cuando solamente se consume una parte finita, el cálculo termina en tiempo finito. Sin embargo, take 10 . filter (/= 'W') . map toUpper $ repeat 'w' no terminaría, ya que ninguno de los caracteres producidos pasa el filter para alcanzar el take 10.

+0

Gracias por la gran respuesta :) ¿Es posible escribir este código en un lenguaje estricto (sin simular pereza)? O en una lengua estricta, la lista se atravesará dos veces, una para el mapa y otra para el filtro, comenzando desde el principio. – Adi

+1

@Adi: sí, habrá dos recorridos de lista. map devolverá una nueva lista intermedia, que pasará a filter, que pasará por y devolverá otra lista – newacct

+5

En un lenguaje estricto (impaciente), uno debería simular la pereza para obtener el mismo comportamiento. Algunos lenguajes lo hacen más fácil que otros, prefiero hacer eso en erlang o F # que en C (y que aunque conozco C, casi no tengo erlang ni F # :). Si hay dos recorridos o uno en un lenguaje entusiasta depende del compilador. En principio, el filtro y el mapa se pueden fusionar, pero en general el compilador necesitaría probar la pureza de la función mapeada y el predicado del filtro para poder hacer eso. Así que espero dos recorridos en la mayoría de los casos, la prueba es difícil. –

Cuestiones relacionadas