Sto cercando di trovare l'implementazione "migliore" di un multi-argomento "componi" in Scheme (so che è incorporato in alcune implementazioni, ma suppongo per il momento che sono usando uno che non ha questo).Schema: implementazione di n-argomento comporre usando fold
Per una funzione di composizione 2-argomento ho questo:
(define compose
(lambda (f g)
(lambda x
(f (apply g x)))))
Questo ha il vantaggio che se il più a destra funzione richiede argomenti aggiuntivi, questi possono ancora essere passati attraverso la funzione combinata. Questo ha la piacevole proprietà che la composizione della funzione di identità su qualcosa non modifica la funzione.
Ad esempio:
(define identity
(lambda (x) x))
(define list1
(compose identity list))
(define list2
(compose identity list1))
(list2 1 2 3)
> (1 2 3)
ora per fare un "n-argomento" comporre avrei potuto fare questo:
(define compose-n
(lambda args
(foldr compose identity args)))
((compose-n car cdr cdr) '(1 2 3))
> 3
Ma questo non è più conserva quel simpatico "identità" di proprietà:
((compose-n identity list) 1 2 3)
> procedure identity: expects 1 argument, given 3: 1 2 3
Il problema è che la funzione "iniziale" utilizzata per il comando foldr. Ha costruito:
(compose identity (compose list identity))
Quindi ... Non sono sicuro che il modo migliore intorno a questo. "Foldl" sembrerebbe essere l'alternativa naturale meglio, perché voglio che iniziare con "identità" sul sinistra non il destra ...
Ma un'implementazione ingenuo:
(define compose-n
(lambda args
(foldl compose identity args)))
che funziona (hanno per invertire l'ordine delle applicazioni di funzione):
((compose-n cdr cdr car) '(1 2 3))
> 3
non risolve il problema perché ora finisco per dover mettere la funzione identità a sinistra!
((compose-n cdr cdr car) '(1 2 3))
> procedure identity: expects 1 argument, given 3: 1 2 3
E 'come, ho bisogno di usare "foldr" ma hanno bisogno di un po' diverso valore "iniziale" rispetto alla funzione identità ... o una funzione identità migliore? Ovviamente sono confuso qui!
Mi piacerebbe implementarlo senza dover scrivere un "loop" ricorsivo coda esplicito ... sembra che ci dovrebbe essere un modo elegante per farlo, sono solo bloccato.
[ La risposta di Dirk] (http://stackoverflow.com/questions/1693181/scheme-implementing-n-argument-compose-using-fold/1693202#1693202) (poiché cancellata) ha avuto l'idea giusta: basta usare "valori" invece di 'identity'. Questo è in realtà il metodo con cui realizzo gli exploit 'compose':' (compose) 'restituisce semplicemente' values'. –
Grazie! Il mio unico problema ora è che l'interprete di schemi che sto usando non supporta call-with-values ...Esiste un modo per implementare "valori" e "call-with-values" in aggiunta allo Scheme esistente? –
Ho sviluppato un metodo per ordinare i falsi 'valori' e' call-with-values': nuovo post in arrivo. :-) –