2013-08-02 114 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学习编程语言概念,并为您的学习应用有趣的作业。强烈推荐。