Estoy tratando de encontrar la "mejor" implementación de una "redacción" de múltiples argumentos en Scheme (sé que es un built-in en algunas implementaciones, pero asumo por el momento que estoy usando uno que no tiene esto).Esquema: Implementar n-argumentos componer utilizando fold
Para una función de composición 2-argumento tengo esto:
(define compose
(lambda (f g)
(lambda x
(f (apply g x)))))
Esto tiene la ventaja de que si el extremo derecho función necesita argumentos adicionales, estos pueden todavía ser transmitidos a través de la función combinada. Esto tiene la agradable propiedad de que componer la función de identidad sobre algo no cambia la función.
Por ejemplo:
(define identity
(lambda (x) x))
(define list1
(compose identity list))
(define list2
(compose identity list1))
(list2 1 2 3)
> (1 2 3)
ahora para hacer una "n-argumento" Componer que podía hacer esto:
(define compose-n
(lambda args
(foldr compose identity args)))
((compose-n car cdr cdr) '(1 2 3))
> 3
Pero esto ya no conserva que linda propiedad "identidad":
((compose-n identity list) 1 2 3)
> procedure identity: expects 1 argument, given 3: 1 2 3
El problema es que la función "inicial" se utiliza para el comando foldr. Ha construido:
Así que ... No estoy seguro de la mejor manera de evitar esto. "Foldl" parece ser la mejor alternativa natural, porque quiero que comenzar con la "identidad" de la izquierda no el derecho ...
embargo, una aplicación ingenua:
(define compose-n
(lambda args
(foldl compose identity args)))
que funciona (tiene que invertir el orden de las aplicaciones de función):
((compose-n cdr cdr car) '(1 2 3))
> 3
no resuelve el problema, porque ahora me acaban de tener que poner la función de la identidad de la izquierda!
((compose-n cdr cdr car) '(1 2 3))
> procedure identity: expects 1 argument, given 3: 1 2 3
Es como, tengo que utilizar "foldr", pero necesita algo de valor diferente "inicial" de la función identidad ... o una función identidad mejor? ¡Obviamente estoy confundido aquí!
Me gustaría implementarlo sin tener que escribir un explícito "bucle" recursivo de cola ... parece que debe haber una manera elegante de hacerlo, solo estoy atascado.
[ La respuesta de Dirk] (http://stackoverflow.com/questions/1693181/scheme-implementing-n-argument-compose-using-fold/1693202#1693202) (desde que se eliminó) tuvo la idea correcta: simplemente use 'values' en lugar de 'identidad'. Este es en realidad el método en que mi implementación de exploits 'comose':' (compose) 'simplemente devuelve' values'. –
Gracias! Mi único problema ahora es que el intérprete de esquemas que estoy usando doens't support call-with-values ...¿Hay alguna forma de implementar "valores" y "call-with-values" sobre el esquema existente? –
He desarrollado una forma de ordenar los 'valores' y' call-with-values' falsos: nueva publicación entrante. :-) –