C'è un nome per la funzione che restituisce un posizionalmente di espansione della versione della sua tesi?

StackOverflow https://stackoverflow.com/questions/9439117

  •  12-11-2019
  •  | 
  •  

Domanda

Considerare splatter in questo codice Python:

def splatter(fn):
    return lambda (args): fn(*args)

def add(a, b):
    return a + b

list1 = [1, 2, 3]
list2 = [4, 5, 6]
print map(splatter(add), zip(list1, list2))

La mappatura di un n-ary funzione di n zippato sequenze sembra un comune abbastanza operazione che ci potrebbe essere un nome per questo già, ma non ho idea di dove mi piacerebbe trovare che.Vagamente evoca currying, e sembra che ci sono probabilmente altre tesi-centric HOFs che non ho mai sentito parlare.Qualcuno sa se questo è un "noto" funzione?Quando si parla di esso io sono bloccato con il tipo di imbarazzante lingua utilizzata nel titolo della domanda.

Modifica

Wow, Python map lo fa automaticamente.Si può scrivere:

map(add, list1, list2)

E farà la cosa giusta, vi risparmio la fatica di splattering funzione.L'unica differenza è che zip restituisce un elenco la cui lunghezza è la lunghezza del più breve argomento, mentre map si estende più brevi elenchi con None.

È stato utile?

Soluzione 2

Ho casualmente visto questo nella mia lista delle "Domande frequenti" e fu sorpreso che ora conosco la risposta.

Ci sono due interpretazioni della funzione che ho chiesto.

Il primo era il mio intento:per scattare una funzione che prende un numero fisso di argomenti e di convertirlo in una funzione che prende tali argomenti, come una dimensione fissa di lista o di una tupla.In Haskell, la funzione che esegue questa operazione si chiama uncurry.

uncurry :: (a -> b -> c) -> ((a, b) -> c)

(Parentesi Extra per maggiore chiarezza).

È facile immaginare che si estende questo per funzioni di più di due argomenti, anche se non può essere espresso in Haskell.Ma uncurry3, uncurry4, etc.non sarebbe fuori luogo.

Così mi è stato giusto che "vagamente evoca currying", come in realtà è il contrario.


La seconda interpretazione è quello di prendere una funzione che prende un intenzionalmente numero variabile di argomenti e di ritorno di una funzione che accetta un unico elenco.

Perché splat è così strano come una costruzione sintattica in Python, questo è difficile ragionare su.

Ma se pensiamo, diciamo, di JavaScript, che è una di prima classe denominata funzione di "splatting:"

varFn.apply(null, args)

var splatter = function(f) {
    return function(arg) {
        return f.apply(null, arg);
    };
};

Quindi si potrebbe parafrasare che come una mera applicazione parziale della "apply"la funzione:

var splatter = function(f) {
    return Function.prototype.apply.bind(f, null);
};

O che utilizza, Underscore s partial, siamo in grado di venire con la punto-free definizione:

var splatter = _.partial(Function.prototype.bind.bind(Function.prototype.apply), _, null)

Sì, è un incubo.

(L'alternativa per _.partial richiede la definizione di una sorta di swap helper e sarebbe uscito anche meno leggibile, credo.)

Quindi penso che il nome di questa operazione è solo "una parziale applicazione di apply"o in Python caso, è quasi come un sezione di splat operatore -- se splat un "effettivo" dell'operatore.


Ma la particolare combinazione di uncurry, zip, e map per la domanda originale è esattamente zipWith, come chris ha sottolineato.Infatti, HLint per impostazione predefinita include una regola per sostituire questo complesso di costruire con una singola chiamata a zipWith.


Spero che cancella le cose, il passato di Ian.

Altri suggerimenti

Penso zipWith è la funzione ricerca (questo nome è usato almeno in Haskell).È anche un po ' più generale.In Haskell zipWith è definito come segue (dove la prima riga è proprio il tipo):

zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
zipWith _ _      _      = []

E il tuo esempio sarebbe qualcosa di simile

zipWith (+) [1, 2, 3] [4, 5, 6]

Dal momento che non conosco python molto bene, posso solo scegliere "zipWith analogico in Python?".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top