首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >函数在OCaml中不带args和返回类型。

函数在OCaml中不带args和返回类型。
EN

Stack Overflow用户
提问于 2013-12-11 09:09:02
回答 2查看 941关注 0票数 0

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

代码语言:javascript
运行
复制
# let rec flat = function
    [] -> []
    | h :: t -> h @ flat t;;

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

OCaml解释器如何知道:

  1. 我的函数flat需要一个参数,即“列表”。
  2. 平面返回类型是一个列表。解释器用[] -> []行检查它吗?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-11 09:50:57

代码语言:javascript
运行
复制
let rec flat = function
    [] -> []
    | h :: t -> h @ flat t;;

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

代码语言:javascript
运行
复制
let rec flat l = 
  match l with
      [] -> []
    | h :: t -> h @ flat t

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

您的函数是递归的。[] -> []是基本情况,也是函数将被停止的地方。是的,解释器用[] -> []检查它。

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

让我们举一个例子:

代码语言:javascript
运行
复制
let f1 = Random.int 10;

f1没有任何参数,即使没有() (在这里,()就像一个没有任何参数的方法)。然后,f1是由Random生成的常量值。无论您何时调用它,f1都将永远是固定的。

代码语言:javascript
运行
复制
let f2 () = Random.int 10;

f2是一个函数。每次调用f2()时,内部的Random将生成一个随机输入并返回它。

票数 1
EN

Stack Overflow用户

发布于 2013-12-11 23:54:47

代码语言:javascript
运行
复制
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,我们将看到应用于hflat t的列表连接操作符@。这意味着h必须是一个列表,并且必须是与flat t相同的列表。因此,输入列表的元素是列表,函数的输出也是如此。

这给了你flat : 'a list list -> 'a list

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

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

  • 在第一个分支中,返回一个列表[]
  • 在第二个分支中,返回@的结果,@返回列表
  • 同样在第二个分支中,flat t被递归地调用,然后作为参数提供给@。因为它是@的一个参数,所以它必须是一个列表,所以flat必须返回一个列表。

第三个要点特别有趣,因为它向您展示的不仅仅是如何创建值来决定它们的类型,还在于您如何使用它们。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20514892

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档