2013-08-02 113 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可以是任何類型,所以功能是多態性其類型,它表示爲類型變量'a。整個函數的類型'a * (float * float) -> float * float指示對於任何類型'a,您可以傳遞一個'a(float * float)的元組,並且它將返回一個(float * float)

這是snd功能的特定情況下:其類型'a * 'b -> 'b

let snd (x, y) = y 

:對於任何'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學習編程語言概念,併爲您的學習應用有趣的作業。強烈推薦。