2013-08-02 12 views
7

Uczę się programowania funkcjonalnego i używam Ocaml, ale mam problem z funkcjami.Funkcjonalna funkcja programowania zamieszania

W każdym razie mam krotkę i chcę zwrócić jej pierwszą wartość. (Bardzo proste wiem, przepraszam)

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

Wszystko dobrze i dobrze tutaj.

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

To właśnie mnie wprawia w zakłopotanie. Dlaczego jest tam 'a? Wiem, że oznacza zmienną o nieznanym typie, ale nie rozumiem, w jaki sposób zmienia się wartość zwracana.

Jestem self wyznawaną n00b w programowaniu funkcjonalnym, proszę nie jeść mnie :)

Odpowiedz

10

Zostałaś ugryziona przez subtelną składni pomyłkę, która jest naprawdę nieoczywisty dla początkujących:

let foo x : t = bar 

to nie to samo co

let foo (x : t) = bar 

jest na równowartość wbrew

let foo x = (bar : t) 

ograniczenie typu zwrotu funkcji.

.

Więc napisałem

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

Typ wejścia jest para, której drugi element, y, ma typ float * float. Ale x może być dowolnego typu, więc funkcja jest w typie polimorficzna, którą reprezentuje jako zmienną typu 'a. Typ całej funkcji, 'a * (float * float) -> float * float, oznacza, że ​​dla dowolnego typu 'a można przekazać krotkę z 'a i (float * float), która zwróci wartość (float * float).

Jest to szczególny przypadek funkcji snd:

let snd (x, y) = y 

który ma typ 'a * 'b -> 'b: dla każdego 'a i 'b, wziąć parę ('a * 'b) i zwraca wartość typu 'b.

1

W obu przykładach podajesz ograniczenia typu dla wyniku zdefiniowanej funkcji, zamiast jej argumentu (co prawdopodobnie było zamierzone).

Zatem

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

oznacza, że ​​wynik john (tj y) powinny być typu (float * float). Teraz, ponieważ na wejściu mamy parę składającą się z x (z czego nic nie wiadomo) i y (typu float * float), ostateczny typ dla wejścia to 'a * (float * flat).

Aby dostać to, co chcesz, możesz użyć:

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

Jeśli chcesz dowiedzieć się SML i programowanie funkcjonalne w ogóle, Programming Languages kurs będzie oferowana w Coursera ponownie. Nauczysz się koncepcji języka programowania SML, Racket i Ruby i będziesz miał przyjemne zadania, aby zastosować to, czego się nauczyłeś. Wysoce polecany.

Powiązane problemy