2013-08-02 8 views
7

Sto imparando la programmazione funzionale e sto usando Ocaml, ma sto avendo un po 'di problemi con le funzioni.Confusione funzione di programmazione funzionale

In ogni caso, ho una tupla e voglio restituire il suo primo valore. (Molto semplice, lo so, scusa)

let bach (x,y):(float*float) = (x,y);; 
val bach : float * float -> float * float = <fun> 

Tutto bene qui.

let john (x,y):(float*float) = y;; 
val john : 'a * (float * float) -> float * float = <fun> 

Ora questo è ciò che mi confonde. Perché c'è un 'a lì? So che sta per una variabile con un tipo sconosciuto, ma sono confuso su come la modifica del valore di ritorno aggiunga che lì.

Io sono un self n00b professato nella programmazione funzionale, per favore non mi mangiare :)

risposta

10

Lei è stato morso da un errore di sintassi sottile che è in realtà non ovvia per i principianti:

let foo x : t = bar 

non è la stessa come

let foo (x : t) = bar 

è l'equivalente contrariamente a

let foo x = (bar : t) 

vincolando il tipo di ritorno della funzione.

.

Quindi hai scritto

let john (x, y) = (y : float * float) 

Il tipo di input è una coppia il cui secondo elemento, y, ha digitare float * float. Ma x può essere di qualsiasi tipo, quindi la funzione è polimorfa nel suo tipo, che rappresenta come una variabile di tipo 'a. Il tipo dell'intera funzione, 'a * (float * float) -> float * float, indica che per qualsiasi tipo 'a, è possibile passare una tupla di uno 'a e uno (float * float) e restituirà uno (float * float).

Questo è un caso particolare della funzione snd:

let snd (x, y) = y 

che ha tipo 'a * 'b -> 'b: per ogni 'a e 'b, si prende una coppia ('a * 'b) e restituire un valore di tipo 'b.

1

In entrambi gli esempi si stanno dando vincoli di tipo per il risultato della funzione definita, anziché il suo argomento (come probabilmente era inteso).

Così

let john (x, y) : (float * float) = y;; 

significa che il risultato di john (cioè, y) dovrebbe essere di tipo (float * float). Ora, poiché nell'input abbiamo una coppia composta da x (di cui non si sa nulla) e (di tipo float * float), il tipo finale per l'input è 'a * (float * flat).

per ottenere ciò che si desidera, è possibile utilizzare:

let john ((x:float), (y:float)) = y;; 
-1

Se volete imparare OCaml e programmazione funzionale in generale, Programming Languages corso sta per essere offerto a Coursera di nuovo. Imparerai concetti di linguaggio di programmazione da SML, Racket e Ruby e avrai compiti divertenti per applicare ciò che impari. Altamente raccomandato.