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]
复制代码
|
分享到:
相关推荐
book about the functional programming language ocaml. You really shouldn't miss it.
OCaml编程模式 目的 该软件包包含一些随机的编程技巧,“设计模式”,以及随着时间的推移,我在OCaml程序中实现高抽象水平的其他有用或至少启发性的想法。 一些可能展示了如何实现或多或少具有理论意义的概念(例如...
对于OCaml识字的编程工具.gz
OCaml,教程英文版。
OCaml的介绍,OCaml是一种为表达,安全和速度而设计的工业级编程语言。 里面的示例将帮助读者快速了解OCaml作为编写快速,简洁和易读的系统代码的工具如何脱颖而出。
这是Caml和OCaml(目标Caml)编程的上一页,我们正在处理中,将那里的所有书籍都转换为新页面。 请稍后检查此页面!!!
[奥莱理] OCaml 开发实战 (英文版) [奥莱理] Real World OCaml (E-Book) ☆ 图书概要:☆ This fast-moving tutorial introduces you to OCaml, an industrial-strength programming language designed for ...
关于OCaml的一本好书
Fan是OCaml的功能齐全的元编程系统,它是带有Lispy的的超集。 主页: : 要求ocaml(== 4.00.1)ocamlfind(可选) 安装 make world 如果您已安装ocamlfind,请尝试make metainstall来安装META文件
OCaml入门
设置OCaml 设置OCaml和opam环境并添加到PATH。 状态 高度不稳定和不完整。 如果您使用此,请您自己承担风险完全使用这个(在这个非常时刻)。
Objective Caml(OCaml)是Caml编程语言的主要实现 多范氏:A functional programming language descendent of ML,imperative, and object-oriented A powerful type system(得益于ML的体系) 强大的编译...
最近由于项目需要,需要用OCaml语言去实现一个循环队列去实现一些功能。翻遍了Ocaml的官方网站和标准库,发现OCaml只提供普通的队列,于是自己基于Array模块设计了循环队列RoundRobinQueue的模块。能够实现Queue中的...
Atom-language-ocaml-fix.zip,atom编辑器的ocaml语法定义ocaml原子包,atom是一个用web技术构建的开源文本编辑器。
这是在网上找到的关于ocaml的学习文件,由于是法语书大家看起来有些困哪,可以结合法语助手看,对有PF课程的朋友很有帮助。
Real World OCaml
js_of_ocaml, 编译器从OCaml到 Javascript Js_of_ocaml ( jsoo )Js_of_ocaml是一个编译器从OCaml字节码到 JavaScript 。 它使得在JavaScript环境中运行纯OCaml程序成为可能,如浏览器和 Node.js.它很容易安装和使用
ocaml reference manual. you'll find it useful.
HardCaml 是设计硬件的 OCaml 库:使用 OCaml 表达硬件设计使用高需求函数,列表,映射,functors 创建常规设计使用 OCaml 模拟设计 转换成 VHDL, Verilog, C编写新模块变换或者分析电路,提供新后端 标签:...
Objective Caml (OCaml) 是Caml编程语言的主要实现,由Xavier Leroy, Jérôme Vouillon, Damien Doligez, Didier Rémy及其他人于1996年创立。OCaml是开放原代码项目。此项目的管理和大部分维护工作交由INRIA ...