2013-08-02 3 views
7

Я изучаю функциональное программирование и использую Ocaml, но у меня проблема с функциями.Функция функционального программирования путаница

Во всяком случае, у меня есть кортеж, и я хочу вернуть его первое значение. (Очень просто знаю, извините)

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

Все хорошо и хорошо здесь.

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

Теперь вот что меня смущает. Почему там 'a? Я знаю, что это означает переменную с неизвестным типом, но я смущен тем, как меняется добавленное туда возвращаемое значение.

Я самостоятельно исповедовали n00b в функциональном программировании, пожалуйста, не ешь меня :)

ответ

10

Вы были укушены тонким синтаксической ошибкой, которая действительно неочевидный для начинающих:

let foo x : t = bar 

это не то же самое, как

let foo (x : t) = bar 

это наоборот, эквивалентном

let foo x = (bar : t) 

ограничение типа возврата функции.

.

Итак, вы написали

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

Тип входного пара, чей второй элемент, y, имеет тип float * float. Но x может быть любого типа, поэтому функция polymorphic в своем типе, который он представляет как переменную типа 'a. Тип всей функции, 'a * (float * float) -> float * float, указывает, что для любого типа 'a вы можете передать кортеж 'a и (float * float), и он вернет (float * float).

Это частный случай функции snd:

let snd (x, y) = y 

, который имеет тип 'a * 'b -> 'b: для любого 'a и 'b, вы берете пару ('a * 'b) и возвращает значение типа 'b.

1

В обоих примерах вы указываете ограничения типа для результата определенной функции вместо своего аргумента (как это было возможно).

Так

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

означает, что результат john (т.е. y) должен быть типа (float * float). Теперь, поскольку на входе мы имеем пару, состоящую из x (из которых ничего не известно) и y (типа float * float), окончательный тип для ввода - 'a * (float * flat).

Чтобы получить то, что вы хотите, вы можете использовать:

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

Если вы хотите узнать OCaml и функционального программирования в целом, Programming Languages курс будет предлагаться на Coursera снова. Вы изучите концепции языка программирования с помощью SML, Racket и Ruby и получите увлекательные задания для применения того, что вы узнаете. Настоятельно рекомендуется.

Смежные вопросы