2013-08-02 5 views
7

J'apprends la programmation fonctionnelle et j'utilise Ocaml, mais j'ai un peu de problème avec les fonctions.Fonction de programmation fonctionnelle confusion

De toute façon, j'ai un tuple et je veux retourner sa première valeur. (Très simple, je sais, désolé)

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

Tout va bien ici.

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

Maintenant, c'est ce qui me rend confus. Pourquoi y a-t-il un 'a? Je sais que cela signifie une variable avec un type inconnu, mais je suis confus quant à la façon dont le changement de la valeur de retour ajoute que là.

Je suis un n00b auto professé dans la programmation fonctionnelle, s'il vous plaît ne me mange pas :)

Répondre

10

Vous avez été mordu par une erreur de syntaxe subtile qui est vraiment pas évident pour les débutants:

let foo x : t = bar 

n'est pas la même chose que

let foo (x : t) = bar 

il est au contraire équivalent à

let foo x = (bar : t) 

contraint le type de retour de la fonction.

.

Vous avez écrit

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

Le type d'entrée est une paire dont le second élément, y, a le type float * float. Mais x peut être de n'importe quel type, donc la fonction est polymorphe dans son type, qu'il représente comme une variable de type 'a. Le type de la fonction entière, 'a * (float * float) -> float * float, indique que pour tout type 'a, vous pouvez passer un tuple d'un 'a et un (float * float), et il renverra un (float * float).

Ceci est un cas particulier de la fonction snd:

let snd (x, y) = y 

qui a le type 'a * 'b -> 'b: pour tout 'a et 'b, vous prenez une paire ('a * 'b) et retourne une valeur de type 'b.

1

Dans vos deux exemples, vous donnez des contraintes de type pour le résultat de la fonction définie, au lieu de son argument (comme c'était probablement voulu).

Ainsi

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

signifie que le résultat de john (à savoir, y) doit être de type (float * float). Maintenant, puisque dans l'entrée nous avons une paire composée de x (dont rien n'est connu) et y (de type float * float), le type final pour l'entrée est 'a * (float * flat).

obtenir ce que vous voulez, vous pouvez utiliser:

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

Si vous voulez apprendre Ocaml et la programmation fonctionnelle en général, Programming Languages cours va être offert à nouveau Coursera. Vous apprendrez les concepts de langage de programmation de SML, Racket et Ruby et vous aurez des devoirs amusants pour appliquer ce que vous apprenez. Hautement recommandé.

Questions connexes