Al leer este artículo clásico , estoy atrapado en paramorfismos. Desafortunadamente, la sección es bastante delgada y la página de Wikipedia no dice nada.
Mi traducción de Haskell es:
para :: (a -> [a] -> b -> b) -> b -> [a] -> b
para f base = h
where
h [] = base
h (x:xs) = f x xs (h xs)
Pero no asimilo eso, no tengo ninguna intuición para la firma tipográfica o el resultado deseado.
¿Qué es un paramorfismo y cuáles son algunos ejemplos útiles en acción?
Sí, he visto estas preguntas , pero no cubren los paramorfismos directamente y solo apuntan a recursos que pueden ser útiles como referencias, pero no como materiales de aprendizaje.
haskell
recursion
functional-programming
higher-order-functions
Matt Fenwick
fuente
fuente

para f base xs = foldr (uncurry f) base $ zip xs (tail $tails xs), me parece.para f base xs = foldr g base (init $ tails xs) where g (x:xs) = f x xs. Esto recuerda a Common Lispmaplist.Respuestas:
Sí, eso es
para. Compare con catamorfismo, ofoldr:Algunas personas llaman a los paramorfismos "recursividad primitiva" en contraste con los catamorfismos (
foldr) que son "iteración".Donde
foldrlos dos parámetros reciben un valor calculado de forma recursiva para cada subobjeto recursivo de los datos de entrada (aquí, esa es la cola de la lista),paralos parámetros obtienen tanto el subobjeto original como el valor calculado de forma recursiva a partir de él.Una función de ejemplo que se expresa muy bien con
paraes la colección de los suficientes suficientes de una lista.así que eso
Posiblemente más simple aún es
en el que la rama "contras" ignora su argumento calculado de forma recursiva y simplemente devuelve la cola. Evaluado con pereza, el cálculo recursivo nunca ocurre y la cola se extrae en tiempo constante.
Puede definir
foldrusandoparabastante facilidad; que es un poco más difícil de definirparaa partirfoldr, pero es ciertamente posible, y todo el mundo debe saber cómo se hace!El truco para definir
paraconfoldres reconstruir una copia de los datos originales, de modo que obtengamos acceso a una copia de la cola en cada paso, aunque no tuviéramos acceso al original. Al final,snddescarta la copia de la entrada y da solo el valor de salida. No es muy eficiente, pero si te interesa la expresividad pura,parano te da más quefoldr. Si usa estafoldrversión codificada depara, luegosafeTailtomará un tiempo lineal después de todo, copiando la cola elemento por elemento.Entonces, eso es todo:
paraes una versión más conveniente de lafoldrcual le brinda acceso inmediato al final de la lista, así como al valor calculado a partir de ella.En el caso general, trabajar con un tipo de datos generado como el punto fijo recursivo de un funtor
tienes
y de nuevo, los dos son mutuamente definibles,
paradefinidoscatapor el mismo truco "hacer una copia"De nuevo,
parano es más expresivocata, pero es más conveniente si necesita un fácil acceso a las subestructuras de la entrada.Editar: Recordé otro buen ejemplo.
Considere los árboles de búsqueda binarios dados por
Fix TreeFdondee intente definir la inserción para árboles de búsqueda binarios, primero como a
cata, luego como apara. Encontrará laparaversión mucho más fácil, ya que en cada nodo deberá insertar un subárbol pero conservar el otro tal como estaba.fuente