2012-06-27 4 views
8

Questo potrebbe rientrare in "non si può, e non c'è ragione per lo meno," ma sono curioso di sapere se è possibile. Almeno, forse sarà un divertente R puzzle.Come curry a ... argomento per posizione in R?

stavo meditando di scrivere cat per aggiungere sempre \n. Tuttavia, cat viene scritto in modo che incolli insieme tutti gli argomenti assegnati (tramite ...).

Sorprendentemente, questo funziona:

> library(functional) 
> catnip <- Curry(cat, "\n") 
> catnip("hi") 

hi 

Tuttavia, il \n venti fino prima di testo dell'utente. C'è un modo per eseguire il curry della funzione in modo tale da specificare che l'argomento al curry termina sempre gli argomenti ...?

+4

Gatto al curry, gnam! – John

+1

Nifty risponde a tutti. La mia padronanza di 'do.call' è incompleta ma progressiva. Grazie :-) –

risposta

10

Sembra che Curry() legga in modo abbastanza efficace i due elenchi di argomenti nell'ordine opposto rispetto a quello che desideri. È comunque una funzione abbastanza semplice, che puoi semplicemente costruire la sua immagine speculare e usarla al suo posto.

Curry2 <- function(FUN, ...) { 
    .orig = list(...) 
    function(...) do.call(FUN, c(list(...), .orig)) 
} 

catnip <- Curry2(cat, "\n") 
catnip("hi") 
7

# 1. Ignora il secondo argomento di Curry e codice hard il newline

Prova questo che alza l'ultimo argomento di cat codificandolo su una funzione anonima. E 'in realtà non fa uso di Curry argomenti dopo il primo:

catnip <- Curry(function(...) cat(..., "\n")) 

# 2. funzione di produzione per accattivarsi una funzione anonima

Ecco una seconda soluzione, che striglia l'ultimo argomento di cat utilizzando una funzione anonima che riordina gli argomenti s' cat.

catnip2 <- Curry(function(last.arg, ...) cat(..., last.arg), "\n") 

# test 
catnip2("hi", "there") 

# 3. Produzione funzione desiderata facendo una funzione ancora più semplice

Forse il vero punto di tutto questo è vedere come possiamo prendere i componenti di base e Curry per ottenere ciò che vogliamo. Così potremmo definire un generale last.arg.fun e quindi produrre la funzione desiderata da un curry di esso:

last.arg.fun <- function(FUN, last.arg, ...) FUN(..., last.arg) 
catnip3 <- Curry(last.arg.fun, cat, "\n") 

# test 
last.arg.fun(cat, "\n", "hi", "there") 

# test 
catnip3("hi", "there") 

Potremmo farlo in due fasi se abbiamo bisogno last.arg.cat ad un certo punto:

last.arg.cat <- Curry(last.arg.fun, cat) 
catnip4 <- Curry(last.arg.cat, "\n") 

# test 
last.arg.cat("\n", "hi", "there") 

# test 
catnip4("hi", "there") 

noti che ciascuno dei test dovrebbe produrre una riga che dice ciao finito in una nuova riga.

EDIT: più soluzioni.