Stile di programmazione funzionale: come scrivere funzioni - curriculum esplicito, curriculum implicito o lamdas?

2

Quindi ho usato F # per un po 'e ho studiato un po' di Haskell sul lato e ho realizzato che avrei potuto riscrivere la stessa identica funzione in tre modi diversi.

O con curriculum implicito, curriculum esplicito o con espressioni lambda.

//lambdas
let add'  =  fun x -> fun y -> x + y

//explicit currying
let add' x  =     
   let subFunction y = 
      x + y                    
   subFunction   

//implicit currying
let add' x y = x + y

Tutti questi hanno la firma int - > int - > Int. Tutti loro fanno la stessa cosa

Quale dovrei usare nel qual caso?

    
posta Alexander Ryan Baggett 02.03.2015 - 09:23
fonte

2 risposte

5

Nelle situazioni simili a quella che hai descritto devi sempre usare la terza opzione, o, meglio ancora, solo let add' = (+) (ma fai attenzione a Restrizione del monomorfismo ). Non ho senso nelle altre due definizioni che hai fornito.

Tuttavia, è comune usare funzioni annidate in un modo simile al secondo esempio se la funzione nidificata accetta argomenti ausiliari, come un accumulatore in funzioni ricorsive in coda.

    
risposta data 02.03.2015 - 10:47
fonte
2

La risposta alla tua domanda è l'opzione "curriculum implicito". Tuttavia, ci sono momenti in cui dovresti usare la seconda opzione.

In Haskell, per prestazioni, potresti voler condividere del lavoro nel risultato parzialmente applicato. (Nota, nulla nel Report garantisce questa condivisione o impedisce al compilatore di sollevare il lavoro stesso. In pratica, GHC non esegue questo tipo di trasformazione per buone ragioni.)

addC x = let c = large computation x in \y -> x + y + c

In Haskell questo è semanticamente equivalente al seguente, anche se in pratica avrà caratteristiche di performance diverse.

addC x y = let c = large computation x in x + y + c

In F # la differenza può essere semanticamente significativa.

let foo x = let rx = ref x in fun y -> rx := !rx + 1; !rx + y;;

è molto diverso da

let foo x y = let rx = ref x in rx := !rx + 1; !rx + y;;
    
risposta data 17.01.2016 - 09:23
fonte

Leggi altre domande sui tag