Ocaml编程速览
来自http://bbs.9ria.com/thread-77807-1-1.html
一旦你了解了OCaml便会感到它是一门非常神奇的语言,不过学习它的第一步却是非常困难的。希望这个小小的教程可以让事情变得简单些。首先OCaml不是一个结构化语言,它属于函数语言家族。纯粹的函数语言没有提供循环机制(你需要使用递归来完成循环),变量也不可改变,以及其它的一些限制。幸运的是OCaml不是一个纯粹的函数语言因此可以使用循环与更改变量。现在让我们开始OCaml的探险历程吧:)
首先让我们启动OCaml,在命令提示符下输入 ocaml 。你将看到下面的内容:
- Objective Caml version 3.04
- #
复制代码
#号是OCaml解释器的提示符,我们已经启动了它。
类型
Ocaml是强类型语言:这表示变量一旦建立就不能改变类型,并且你不可以在两种不同的类型间进行操作(比如将整数与浮点数相加)。让我们来作一些基本的数学计算:
';;'是表达式的结束符,它类似于句子的句号。第二行显示的是结果与结果的类型(int)。我说过不同类型是不能混合计算的,让我们看看这样作会出现什么:
- # 2 + 2.5;;
- This expression has type float but is here used with type int
复制代码
你将会看到在2.5下有一条下划线(我无法在这里打出数字下面的下划线)同时得到第二行中的错误信息。它告诉了你一些什么呢?它告诉你,你的函数只能操作整数,但2.5却是一个浮点数。那么如何进行浮点数加法呢?对于浮点数的运算我们使用运算符+.(在加号后加一点,就是浮点数操作符)。让我们再来试一下,这次使用运算符+.
- # 2 +. 2.5;;
- This expression has type int but is here used with type float
复制代码
现在下划线跑到2下面去了,并且Ocaml告诉你,你在浮点操作符中使用了一个整数。我们该如何得到它们的和呢?我们需要将表达式中的其中一个数的类型转换为另一个的类型。在这里,如果我们转换2.5到整形,那么我们将丢掉.5(这可能不是我们想要的结果),所以我们将把2转换到浮点数。
- # (float_of_int 2) +. 2.5;;
- - : float = 4.5
复制代码
float_of_int是干什么的? 让Ocaml自己来回答我们吧!
- # float_of_int;;
- - : int -> float = <fun>
复制代码
在上面的表达式中O'caml将告诉我们float_of_int是一个函数(<fun> ) 它接收一个整形参数返回一个浮点值。所以当我们把2传递给float_of_int时,它将返回2.0,这样我们就可以进行计算了。 记住只有相同类型的值才能在一起工作。
整数算术操作符: + : 加 - : 减 * : 乘 / : 除 mod : 取模
浮点操作符: +. : 加 -. : 减 *. : 乘 /. : 除 ** : 幂
转换整数到浮点:float_of_int n 转换浮点到整数:int_of_float n
函数的定义 在Ocaml中,同其它强类型语言一样,函数取得一个预定义类型的参数并返回一个给定类型的值。函数的参数间简单的使用空格分开。 假如我们想定义下面的这些函数,它们的数学形式为:
double : x -> 2X square : x -> x*x cube : x -> x^3
我们该如何在Ocaml中实现它们呢:
- # let double = fun x -> 2. *. x ;;
- # let square = fun x -> x *. x ;;
- # let cube = fun x -> x ** 3. ;;
复制代码
从上面的语法中我们可以看出真正定义函数的部分是从"fun"开始的。而之前的 "let double = "是函数的名字。在Ocaml中也可以使用没有名字的函数。定义函数还可以使用另一种语法:
- # let double x = 2. *. x ;;
- # let square x = x *. x ;;
- # let cube x = x ** 3. ;;
复制代码
注意*号后面的点。它告诉编译器函数仅接受浮点型的参数(因此它也返回一个浮点)。对于函数square如果*号后没有这个点函数将只接受整形参数。这种根据函数使用的语法来推断类型的过程叫作类型推论。这可以使用代码更加易读。为了避免误解,Ocaml的翻译器总是告诉你它推导出的类型。在后面的例子中我将省略这些输入的信息。
函数是first-class类型 这是Ocaml中最有趣的特性,函数是first-class类型,更确切的说,它们可以传递给另一个函数并且可以象任何一般类型(象是整形、浮点、字符串)那样被返回。 让我们通过一个例子来解释它,假设我们希望定义一个由两个函数f与g组合而成的函数,数学定义如下:
f o g : x -> (f o g) (x)= f(g(x))
在Ocaml中这是很简单的:
- let compose f g = fun x -> f(g(x)) ;;
复制代码
如果你够细心,你将注意到几件事: 1. 语法与之前的数学定义非常接近。 2. 我们不需要将x作为一个变量传递给compose函数,我们只要把f与g作为参数传递给compose函数。Ocaml的类型检查器将根据语法x->f(g(x))推导出f与g必须是函数。这里的x是一个虚变量,称为约束变量。 3.comopse函数实际上返回一个函数,是f与g的组合,象下面我们将看到的那样:
- # compose double square 3. ;;
- - : float = 18.
- # compose square double 3.;;
- - : float = 36.
- (* 定义包含一个将参数除2的函数的组合 *)
- # let myfunc = compose square (fun x -> x /. 2.) ;;
- # myfunc 5. ;;
- - : float = 6.25
复制代码
这里,我定义函数myfunc是square函数与一个将输入的参数除2的无名函数的组合。
我们把例子写成下面的样子来展示compose返回函数:
- (* Define a composite with a function that divides its input by 2 *)
- # let myfunc f = compose square f ;;
- # myfunc (fun x -> x /. 2.) 5. ;;
- - : float = 6.25
复制代码
符号化 可以把compose函数定义成一个中缀操作符。操作符可以不包含字母。要将它用为中缀,要把它放入括号之间。如下:
- (* Define the infix operator composite *)
- # let (@) = compose ;;
- # (double@square) 3. ;;
- - : float = 18.
- # (square@double) 3.;;
- - : float = 36.
复制代码
问题:为什么square@double周围需要括号呢?
函数对链的处理 链是函数语言中的一个标准数据结构。使用标准库List.map可以方便让函数的处理一个链中的所有元素,而不用使用循环。如:
- (*create a list of floats *)
- # let v = [1.; 2.; 3.; 4.; 5.] ;;
- # List.map (myfunc@square) v;;
- - : float list = [0.25; 4.; 20.25; 64.; 156.25]
复制代码
为了避免每次都写List.map,可以将代码象下面这样重写:
- (* These new functions take a list of floats as their input and return a list of floats *)
- # let square= fun v -> List.map (fun x-> x *. x) v ;;
- # let myfunc = fun v -> List.map (square@(fun x -> x /. 2.)) v ;;
- # (myfunc@square) v;;
- - : float list = [0.25; 4.; 20.25; 64.; 156.25]
复制代码
|
分享到:
相关推荐
强调了模式匹配在OCaml编程中的广泛应用,不仅是函数定义中,还包括其他多种场景。 #### 五、元组、列表与多态 **多态** - **值限制**: 解释了OCaml中的多态性限制,即某些情况下无法使用泛型类型。 - **其他类型...
"对于OCaml识字的编程工具.gz"这个标题暗示了我们关注的是与OCaml编程相关的软件工具,可能是某种编辑器、IDE或语法高亮插件等,用于提升开发者的编码体验。描述中的".gz"后缀表明这是一个gzip压缩文件,通常用于在...
《Developing Applications With OCaml》是一本专注于使用OCaml编程语言进行应用开发的书籍,它为读者提供了深入理解和掌握OCaml所需的知识体系。OCaml,全称Objective Caml,是Caml的一种方言,属于ML语言家族的一...
从目录结构中可以看出,本书首先介绍了OCaml编程的基础知识,接着深入到递归和命令式编程的高级概念。具体到知识点上,可以细分为以下几个方面: 1. 初识Caml:这部分应该包含了Cam语言的基本概念、如何与Cam进行...
OCaml,作为一种运行在.NET平台上的多范式编程语言,它不仅支持面向对象编程和命令式编程,还特别强调函数式编程。OCaml脚本,即以.ml为扩展名的文件,允许开发者以一种交互式和声明式的方式编写代码。本文将探讨...
在Haskell、OCaml和Python中,虽然它们分别属于不同的编程语言家族,但都支持函数式编程的概念。让我们深入探讨这些语言中的关键函数式编程特性。 1. 纯函数:纯函数是给定相同输入时始终返回相同输出,并且不产生...
OCaml编程模式 目的 该软件包包含一些随机的编程技巧,“设计模式”,以及随着时间的推移,我在OCaml程序中实现高抽象水平的其他有用或至少启发性的想法。 一些可能展示了如何实现或多或少具有理论意义的概念(例如...
标题 "用OCaml开发的国际象棋程序" 暗示了这个项目是使用OCaml编程语言实现的一个国际象棋游戏。OCaml是一种静态类型的、强类型、函数式编程语言,它结合了面向对象和过程编程的特点,具有高效、安全和模块化的优势...
OCaml编程语言是一种静态类型的、编译型的、通用的编程语言,以其强大的类型系统和高效的编译器闻名。在“setup-ocaml”项目中,我们关注的是如何在开发环境中配置OCaml及其相关的工具链,特别是通过GitHub操作来...
OCaml(Objective Caml)是一种多范式、静态类型的编程语言,它结合了函数式、命令式和面向对象的编程风格。"ocaml-3.10.2" 是 OCaml 的一个特定版本,发布于该语言的发展历程中。这个版本在当时可能包含了性能优化...
OCaml是一种现代的通用编程语言,属于函数式编程领域。它以其强大的类型系统、高性能和丰富的库支持而闻名于世。OCaml适用于各种应用场景,从系统编程到网络应用开发均有涉猎。 **本书亮点**: - **无先决条件的...
OCaml的介绍,OCaml是一种为表达,安全和速度而设计的工业级编程语言。 里面的示例将帮助读者快速了解OCaml作为编写快速,简洁和易读的系统代码的工具如何脱颖而出。
这是Caml和OCaml(目标Caml)编程的上一页,我们正在处理中,将那里的所有书籍都转换为新页面。 请稍后检查此页面!!!
1. OCaml编程语言:OCaml是一种多范式的编程语言,它支持函数式编程,是ML语言家族的一个成员。函数式编程强调使用函数来处理数据和控制流程,这在 OCaml 中得到了很好的体现。 2. 函数式编程概念:与面向过程或...
[奥莱理] OCaml 开发实战 (英文版) [奥莱理] Real World OCaml (E-Book) ☆ 图书概要:☆ This fast-moving tutorial introduces you to OCaml, an industrial-strength programming language designed for ...
OCaml是一种强大的、静态类型的、函数式编程语言,以其高效的编译器和强大的类型系统著称。这个语言定义包使得在Atom编辑器中编写OCaml代码时,能够享受到更好的语法高亮、自动完成、错误检测等功能。 语言定义包...