首先,我通常用命令式语言编程,这使我很难解释某些事情。首先是没有args的函数,以及返回类型。示例是使列表扁平化的函数:
# let rec flat = function
[] -> []
| h :: t -> h @ flat t;;
val flat : 'a list list -> 'a list = <fun>OCaml解释器如何知道:
flat需要一个参数,即“列表”。[] -> []行检查它吗?发布于 2013-12-11 09:50:57
let rec flat = function
[] -> []
| h :: t -> h @ flat t;;您使用了function关键字。function是match ... with的快捷方式。所以你写的函数就像
let rec flat l =
match l with
[] -> []
| h :: t -> h @ flat t这就是为什么ocaml知道您的函数有一个参数
您的函数是递归的。[] -> []是基本情况,也是函数将被停止的地方。是的,解释器用[] -> []检查它。
此外,函数必须至少有一个unit parameter which is ()或一个正常参数。如果一个函数没有任何东西,它不是一个函数,相反,它是一个具有固定值的变量。
让我们举一个例子:
let f1 = Random.int 10;f1没有任何参数,即使没有() (在这里,()就像一个没有任何参数的方法)。然后,f1是由Random生成的常量值。无论您何时调用它,f1都将永远是固定的。
let f2 () = Random.int 10;f2是一个函数。每次调用f2()时,内部的Random将生成一个随机输入并返回它。
发布于 2013-12-11 23:54:47
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必须返回一个列表。第三个要点特别有趣,因为它向您展示的不仅仅是如何创建值来决定它们的类型,还在于您如何使用它们。
https://stackoverflow.com/questions/20514892
复制相似问题