2015-08-18 8 views
5

Stavo imparando la programmazione funzionale in Swift tramite Haskell e ho trovato questo interessante concetto di Transducers. Un esempio di codice ha implementato una funzione mapping che fondamentalmente sputa un Trasduttore, dato che passiamo la regola di trasformazione come parametro.Trasduttori in Swift

Inspired, ho subito tradotto ad un equivalente Swift e questo è quello che ho ottenuto:

func mapping < A, B, C> (f: A -> B) -> (((C,B) -> C) -> ((C,A) -> C)) { 
    return { r in 
     return { result, a in 
      return r(result,f(a)) 

     } 

    } 
} 

La mia domanda ora è che notare come la funzione di trasformazione va da A a B ((A -> B)), ma il trasduttore passa da B ad A (((C,B) -> C) -> ((C,A) -> C))? Perché? Sono sicuro che non è una coincidenza, perché quell'ordine conta. Esperti Haskell, chiunque?

risposta

4

Verificare dove si trova effettivamente la chiamata a f. Trasforma un A in un B e il risultato viene utilizzato come argomento per r. Pertanto r deve essere in attesa di B; stiamo utilizzando una funzione A -> B per preelaborare l'input per una funzione (C, B) -> C, risultante in una funzione (C, A) -> C.

In generale questa inversione avviene ogni volta che stiamo trasformando un sistema per cambiare il suo "input". Se stiamo trasformando un sistema per cambiare la sua "uscita", non c'è inversione .

X -> A ---> A -> B ---> B -> Y 

Se ho una funzione A -> B e voglio fare da esso qualcosa che emette Y s, invece, ho bisogno di mappare al di sopra il suo output B -> Y funzione. Questo è noto come covarianza, perché la cosa che voglio cambiare (il B in A -> B) "varia con" la funzione I mappa su di esso (B -> Y). Si dice che B si trovi in ​​una posizione positiva in A -> B.

Se ho una funzione A -> B e voglio ricavarne qualcosa che richiede X s, invece, devo mappare una funzione X -> A sul suo input. Questo è noto come controvarianza, perché la cosa che voglio cambiare (il A in A -> B) "varia contro" la funzione I mappa su di esso (X -> A). Si dice che A si trovi in ​​una posizione negativa in A -> B.


programmazione di ordine superiore significa che possiamo essere la trasformazione di un sistema per cambiare un ingresso entro l'uscita di qualcosa che è un ingresso ad un outpu "del nostro sistema ...! I termini 'posizione negativa' e "posizione positiva" aiuta a suggerire che il negativo di un negativo è positivo, ecc.

+0

Ci è voluto un po 'per ottenere questa risposta. Ho dovuto rinfrescare la mia matematica di ingegneria. Grazie! – avismara

1

L'ordine è invertito perché il tuo mapping agisce sull'argomento. Si sta utilizzando una funzione A -> B per rendere una coppia (C,A) adatta al tipo di una funzione (C,B) -> C. Quindi quello che ottieni alla fine è una funzione (C,A) -> C che converte lo A nella coppia in uno B come passaggio preliminare.

Su una nota più generale, mapping fornisce un esempio di un funtore controvariante, al contrario di covariante funtori (ad esempio Haskell Functor classe) in cui l'ordine non viene invertito. Per motivi di illustrazione, ecco uno relevant Haskell package.

+3

Per aggiungere a questa risposta, la controvarianza si verifica quando le variabili di tipo appaiono in posizioni "negative" - ​​cioè, a sinistra della funzione La covarianza si verifica quando le variabili di tipo appaiono sul lato destro della freccia della funzione, in questo caso le variabili di tipo sono 'A' e' B'. Abbiamo controvarianza qui perché in '(C, B) -> C' e (C, A) -> C' sia 'A' che' B' sono in posizioni negative. – ErikR