函数没有args和OCaml中的返回类型

时间:2013-12-11 09:09:03

标签: ocaml

首先,我通常以命令式语言编程,这使我很难解释某些事情。首先是没有args和返回类型的函数。示例是展平列表的函数:

# let rec flat = function
    [] -> []
    | h :: t -> h @ flat t;;

val flat : 'a list list -> 'a list = <fun>

OCaml解释器如何知道:

  1. 我的函数flat只需要一个参数,即“列表列表”。
  2. Flat返回类型是一个列表。解释器是否使用[] -> []行进行检查?

2 个答案:

答案 0 :(得分:1)

let rec flat = function
    [] -> []
    | h :: t -> h @ flat t;;

您使用了function个关键字。 functionmatch ... with的快捷方式。所以你写的函数就像

let rec flat l = 
  match l with
      [] -> []
    | h :: t -> h @ flat t

这就是为什么ocaml知道你的函数有一个参数


您的函数是递归的。 [] -> []是基本情况,也是函数停止的地方。是的,口译员用[] -> []检查它。


此外,函数必须至少具有unit parameter which is ()或普通参数。如果一个函数没有任何东西,它就不是一个函数,而是一个具有固定值的变量。

我们举个例子:

let f1 = Random.int 10;

f1没有任何参数,即使没有()(这里()就像Java中没有任何参数的方法)。然后f1是由Random生成的常数值。无论你什么时候打电话,f1都会被修复。

let f2 () = Random.int 10;

f2是一个功能。每次拨打f2()时,Random内部都会生成随机并返回。

答案 1 :(得分:1)

let rec flat = function
    [] -> []
    | h :: t -> h @ flat t;;

让我们一步一步完成这一步。正如您所料,function关键字提供了一个功能。基本语法是function | pat1 -> branch1 | pat2 -> branch2,你得到的是一个参数的函数,它试图依次匹配每个模式的参数,并且匹配结果的第一个模式是相应的分支。

这就是我们如何知道flat是一个函数。此外,我们可以看到它的一个参数与[]匹配,这是一个列表。所以flat必须是一个列表的函数。我们看到如果输入为[],则输出为[],因此它是一个获取列表并返回列表的函数。

现在让我们看看第二种模式。 h :: t是一个匹配列表的模式,并创建两个新的变量绑定:h是列表的第一个元素,t是所有其余元素。特别是,h具有输入列表的元素所具有的任何类型。

如果您看一下如果此模式匹配成功,h @ flat t会发生什么,我们会看到应用于@h的列表并置运算符flat t。这意味着h必须是列表,并且必须与flat t具有相同类型的列表。因此输入列表的元素是列表,函数的输出也是如此。

这会为您提供flat : 'a list list -> 'a list

要直接回答您的问题,flat只需要一个参数,因为它是使用function关键字定义的,而分支的返回值是值而不是函数(如果function分支也是函数,这意味着flat可能有两个或多个参数)。它是一个列表,因为模式匹配是针对列表构造函数的,它是一个列表列表,因为h是列表的一个元素,并与@运算符一起使用,这需要它的参数是列表,所以列表的元素是列表。

返回类型必须是列表实际上有三个原因:

  • 在第一个分支中,返回列表[]
  • 在第二个分支中,返回@的结果,@返回列表
  • 同样在第二个分支中,flat t以递归方式调用,然后作为@的参数给出。由于它是@的参数,因此它必须是一个列表,因此flat必须返回一个列表。

第三个bulet点特别有趣,因为它告诉你,不仅仅是你如何创建决定其类型的值,还有你如何使用它们。

相关问题