OCaml
编程范型 | |
---|---|
语言 | ML |
Xavier Leroy, Damien Doligez, Didier Rémy, Jérôme Vouillon | |
INRIA | |
发行时间 | 1996 |
| |
GNU宽 | |
ocaml | |
衍生 | |
F#, JoCaml, MetaOCaml[4] | |
C, Caml, Modula-2[1], Standard ML | |
ATS, Coq, Elm, F#, F*, Haxe, Opa, Rust, Scala |
OCaml(/oʊˈkæməl/ oh-KAM-əl),
OCaml
历史
哲学
[编辑]ML
OCaml
Xavier Leroy曾经
特 征
[编辑]OCaml
OCaml
OCamlmain
OCaml发行
OCaml
代 码例子
[编辑]OCaml
$ ocaml
OCaml version 4.13.1
#
#
1+2*3
:
# 1 + 2 * 3;;
- : int = 7
OCaml推论int
(7
。
Hello World
[编辑]hello.ml
:
print_endline "Hello World!"
$ ocamlc hello.ml -o hello
$ ocamlopt hello.ml -o hello
$ ./hello
Hello World!
给ocamlchello.ml
,-o hello
标志
阶乘函数
[编辑]很多
let rec fact n =
if n=0 then 1 else n * fact(n - 1);;
这个
let rec fact = function
| 0 -> 1
| n -> n * fact(n - 1);;
编译int -> int
,int
int
。12!
:
# fact 12;;
- : int = 479001600
斐波那 契 序列
[编辑]n
let fib n =
let rec fib_aux m a b =
match m with
| 0 -> a
| _ -> fib_aux (m - 1) b (a + b)
in fib_aux n 0 1;;
生 日 问题
[编辑]let year_size = 365.
let rec birthday_paradox prob people =
let prob = (year_size -. float people) /. year_size *. prob in
if prob < 0.5 then
Printf.printf "answer = %d\n" (people+1)
else
birthday_paradox prob (people+1);;
# birthday_paradox 1.0 1;;
answer = 23
- : unit = ()
合 计整数列 表
[编辑]sum
,它integers
,而它rec
match
语句类似于Cswitch
语句,
let rec sum integers = (* 关键字 rec含义为递归。 *)
match integers with
| [] -> 0 (* 产生0,如果integers为空列 表 []。 *)
| first :: rest -> first + sum rest;; (* 递归调用,如果integers是非 空列 表 ;
first是 这个列 表 的 第 一 个元素 ,
而rest是 余 下 元素 的 列 表 ,可能 是 []。 *)
# sum [1;2;3;4;5];;
- : int = 15
另一种方式是对列表使用标准的fold
let sum integers =
List.fold_left (fun accumulator x -> accumulator + x) 0 integers;;
# sum [1;2;3;4;5];;
- : int = 15
+
let sum integers =
List.fold_left (+) 0 integers
进
let sum =
List.fold_left (+) 0
快速 排 序
[编辑]OCaml
let rec qsort = function
| [] -> []
| pivot :: rest ->
let is_less x = x < pivot in
let left, right = List.partition is_less rest in
qsort left @ [pivot] @ qsort right;;
高 阶函数
[编辑]twice
f
产生应用f
let twice (f : 'a -> 'a) = fun (x : 'a) -> f (f x);;
let inc (x : int) : int = x + 1;;
let add2 = twice inc;;
let inc_str (x : string) : string = x ^ " " ^ x;;
let add_str = twice(inc_str);;
# add2 98;;
- : int = 100
# add_str "Test";;
- : string = "Test Test Test Test"
twice
'a
,'a
f
,而非int->int
twice
甚至
# let fourtimes f = (twice twice) f;;
val fourtimes : ('a -> 'a) -> 'a -> 'a = <fun>
# let add4 = fourtimes inc;;
val add4 : int -> int = <fun>
# add4 98;;
- : int = 102
邱奇数
[编辑]n
f
x
f
x
n
let zero f x = x
let succ n f x = f (n f x)
let one = succ zero
let two = succ (succ zero)
let add n1 n2 f x = n1 f (n2 f x)
let to_string n = n (fun k -> "S" ^ k) "0";;
为了"0"
"S"
to_string
:
# let _ = to_string (add (succ two) two);;
- : string = "SSSSS0"
对象例 子
[编辑]# let x =
object
val mutable x = 5
method get_x = x
method set_x y = x <- y
end;;
val x : < get_x : int; set_x : int -> unit > = <obj>
这里OCaml< get_x : int; set_x : int -> unit >
,x
get_x : int
set_x : int -> unit
而非new
# class simple_cls =
object (self)
val mutable x = 5
method get_x = x
method set_x y = x <- y
end;;
let x = new simple_cls;;
# let y =
object
method get_x = 2
method set_x y = Printf.printf "%d\n" y
end;;
val y : < get_x : int; set_x : int -> unit > = <obj>
OCaml
# x = y;;
- : bool = false
# let set_to_10 a = a#set_x 10;;
val set_to_10 : < set_x : int -> 'a; .. > -> 'a = <fun>
< set_x : int -> 'a; .. >
..
int
set_x
x
# set_to_10 x;;
- : unit = ()
另一个对象可以碰巧有这个方法和方法类型;其他
# let z =
object
method blahblah = 2.5
method set_x y = Printf.printf "%d\n" y
end;;
val z : < blahblah : float; set_x : int -> unit > = <obj>
set_to_10
# set_to_10 z;;
10
- : unit = ()
这get_x
# type simpler_obj = < get_x : int >;;
type simpler_obj = < get_x : int >
对象x
x
x
x
# (x :> simpler_obj);;
- : simpler_obj = <obj>
# (x :> simpler_obj)#get_x;;
- : int = 10
z
# (z :> simpler_obj);;
Error: Type < blahblah : float; set_x : int -> unit > is not a subtype of
simpler_obj = < get_x : int >
The first object type has no method get_x
这
任意 精度 阶乘函数
[编辑]Num
ZArith
sudo apt install libnum-ocaml-dev
,它可以如
#use "topfind";;
#require "num";;
open Num;;
阶乘=/
、*/
-/
let rec fact n =
if n =/ Int 0 then Int 1 else n */ fact(n -/ Int 1);;
这个120!
:
# string_of_num (fact (Int 120));;
- : string =
"6689502913449127057588118054090372586752746333138029810295671352301633557244962989366874165271984981308157637893214090552534408589408121859898481114389650005964960521256960000000000000000000000000000"
绘制图形例 子
[编辑]simple.ml
let () =
ignore (Glut.init Sys.argv);
Glut.initDisplayMode ~double_buffer:true ();
ignore (Glut.createWindow ~title:"OpenGL Demo");
let angle t = 10. *. t *. t in
let render () =
GlClear.clear [ `color ];
GlMat.load_identity ();
GlMat.rotate ~angle: (angle (Sys.time ())) ~z:1. ();
GlDraw.begins `triangles;
List.iter GlDraw.vertex2 [-1., -1.; 0., 1.; 1., -1.];
GlDraw.ends ();
Glut.swapBuffers () in
GlMat.mode `modelview;
Glut.displayFunc ~cb:render;
Glut.idleFunc ~cb:(Some Glut.postRedisplay);
Glut.mainLoop ()
sudo apt install liblablgl-ocaml-dev
,这个
$ ocamlc -I +lablGL lablglut.cma lablgl.cma simple.ml -o simple
$ ocamlopt -I +lablGL lablglut.cmxa lablgl.cmxa simple.ml -o simple
ocamlfind
$ ocamlfind opt simple.ml -package lablgl.glut -linkpkg -o simple
$ ./simple
用 OCaml写 成 的 程 序
[编辑]- Coq,一个形式证明辅助器[20]。
- HOL Light,一个形式证明辅助器。
- Coccinelle,
用 于C程 序 源 代 码变换的 实用工具 。 - Frama-C,
分析 C程 序 的 一 个框架 。 - Flow,Facebook创建
的 用 于推论和检查JavaScript的 静 态类型 的 一 个静 态分析 器 [21]。 - Infer,Facebook创建
的 用 于Java、C、C++和 Objective-C的 静 态分析 器 ,用 来 检测iOS和 Android应用中 的 缺陷 [22]。 - pyre-check,Facebook创建
的 用 于Python的 类型检查器 [23]。 - Hack编程语言编译
器 ,Facebook创建,扩展PHP具有 静 态类型 。 - Haxe编程语言编译
器 。 - WebAssembly
参考 解 释器,它是意 图在web浏览器 内 执行的 低 层字 节码[24]。 - FFTW,C
的 FFT库,它的多数 性能 关键代 码是由 用 OCaml写 的 一 个程序 生成 的 [25]。 - Owl
科学 计算,用 于科学 和 工程 计算的 专用系 统。 - MirageOS,
用 纯OCaml写 的 一 个单一 内 核 编程框 架 [26]。 - Ocsigen,
一 个OCaml的 web应用框 架 。 - Opa,
用 于Web开发的 自由 和 开源的 一 个编程 语言。 - 0install,一个多平台包管理器。
- MLDonkey,
一 个多网络P2P程 序 。 - Unison,一个文件同步器[27]。
参 见
[编辑]- Caml,OCaml
的 先 驱语言 。 - F#,
由 MSR开发,是 一 个基于OCaml的 一 个以.NET为目标的编程语言。 - F*,
由 MSR和 INRIA主 导开发,是 一 个基于OCaml的 依 赖类型 函数 式 程 序 语言。 - Reason,OCaml
的 语法扩展和 工具 链,也可以转译成JavaScript。
有 关书籍
[编辑]- Yaron Minsky, Anil Madhavapeddy. Real World OCaml, Functional programming for the masses, 2nd Edition. 2021 [2021-09-10]. (
原始 内容 存 档于2022-05-14). - Emmanuel Chailloux, Pascal Manoury, Bruno Pagano. Developing Applications With Objective Caml (PDF). 2000 [2021-09-10]. (
原始 内容 (PDF)存 档于2022-02-23). - Jason Hickey. Introduction to the Objective Caml Programming Language. 2002 [2021-09-10]. (
原始 内容 存 档于2021-09-10).
引用
[编辑]- ^ 1.0 1.1 1.2 Xavier Leroy. Manifest types, modules, and separate compilation (PDF). Principles of Programming Languages. 1994 [2021-09-06]. (
原始 内容 (PDF)存 档于2021-10-22). - ^ 2.0 2.1 Didier Rémy. Type inference for records in a natural extension of ML. Research Report RR-1431, INRIA. 1991 [2021-09-10]. (
原始 内容 存 档于2022-04-06).
Didier Rémy, Jérôme Vouillon. Objective ML: a simple object-oriented extension of ML (PDF). 1997 [2021-09-06]. (原始 内容 (PDF)存 档于2022-01-21).
Didier Rémy, Jérôme Vouillon. Objective ML: An effective object-oriented extension to ML (PDF). 1998 [2021-09-06]. (原始 内容 (PDF)存 档于2022-01-20). - ^ OCaml 5.2.0 Release Notes. [2024
年 5月 24日 ]. - ^ MetaOCaml -- an OCaml dialect for multi-stage programming. [2021-08-28]. (
原始 内容 存 档于2021-08-29). - ^ Xavier Leroy. The Caml Light system Release 0.74, documentation and user's guide. 1997 [2021-09-02]. (
原始 内容 存 档于2022-03-08). - ^ Xavier Leroy. The Objective Caml system release 1.07, Documentation and user's manual. 1997 [2021-09-02]. (
原始 内容 存 档于2022-01-23). - ^ A History of Caml. [2021-09-02]. (
原始 内容 存 档于2022-04-13).Our main reason for developing Caml was to use it for sofware development inside Formel. Indeed, it was used for developing the Coq system ……. We were reluctant to adopt a standard that could later prevent us from adapting the language to our programming needs. ……We did incorporate into Caml most of the improvements brought by Standard ML over Edinburgh ML. ……The first implementation of Caml appeared in 1987 and was further developed until 1992. It was created mainly by Ascander Suarez. ……
In 1990 and 1991, Xavier Leroy designed a completely new implementation of Caml, based on a bytecode interpreter written in C. Damien Doligez provided an excellent memory management system. ……In 1995, Xavier Leroy released Caml Special Light, which improved over Caml Light in several ways. In 1995, Xavier Leroy released Caml Special Light, which improved over Caml Light in several ways. First, an optimizing native-code compiler was added to the bytecode compiler. ……Second, Caml Special Light offered a high-level module system, designed by Xavier Leroy and inspired by the module system of Standard ML. ……Didier Rémy, later joined by Jérôme Vouillon, designed an elegant and highly expressive type system for objects and classes. This design was integrated and implemented within Caml Special Light, leading to the Objective Caml language and implementation, first released in 1996 and renamed to OCaml in 2011. - ^ G. Cousineau, P.-L. Curien, M. Mauny. The categorical abstract machine. 1985 [2021-09-03]. (
原始 内容 存 档于2021-09-03). LNCS, 201, Functional programming languages computer architecture, pp.~50-64.
Michel Mauny, Ascánder Suárez. Implementing functional languages in the Categorical Abstract Machine (PDF). 1986 [2021-09-07]. (原始 内容 (PDF)存 档于2022-01-28). LFP '86: Proceedings of the 1986 ACM conference on LISP and functional programming, Pages 266–278. - ^ G. Cousineau, M. Gordon, G. Huet, R. Milner, L. C. Paulson, C. Wadsworth. The ML Handbook, Version 6.2. Internal document. Project Formel, INRIA. July 1985.
Christoph Kreitz, Vincent Rahli. Introduction to Classic ML (PDF). 2011 [2021-09-11]. (原始 内容 (PDF)存 档于2022-01-29).This handbook is a revised edition of Section 2 of ‘Edinburgh LCF’, by M. Gordon, R. Milner, and C. Wadsworth, published in 1979 as Springer Verlag Lecture Notes in Computer Science no 78. ……The language is somewhere in between the original ML from LCF and standard ML, since Guy Cousineau added the constructors and call by patterns. This is a LISP based implementation, compatible for Maclisp on Multics, Franzlisp on VAX under Unix, Zetalisp on Symbolics 3600, and Le Lisp on 68000, VAX, Multics, Perkin-Elmer, etc... Video interfaces have been implemented by Philippe Le Chenadec on Multics, and by Maurice Migeon on Symbolics 3600. The ML system is maintained and distributed jointly by INRIA and the University of Cambridge.
- ^ Guy Cousineau, Gérard Huet. The CAML primer Version 2.6.1. 1990 [2021-09-07]. (
原始 内容 存 档于2022-05-04). RT-0122, INRIA. pp.78.
Pierre Weis, Maria Virginia Aponte, Alain Laville, Michel Mauny, Ascander Suarez. The CAML reference manual Version 2.6.1. 1990 [2021-09-07]. (原始 内容 存 档于2022-04-06). [Research Report] RT-0121, INRIA. pp.491. - ^ Xavier Leroy. The ZINC experiment : an economical implementation of the ML language. 1990 [2021-09-06]. (
原始 内容 存 档于2022-04-06). RT-0117, INRIA. - ^ Linux Weekly News (页面
存 档备份,存 于互联网档案 馆). - ^ ocaml/asmcomp at trunk · ocaml/ocaml · GitHub. GitHub. [2 May 2015]. (
原始 内容 存 档于2022-05-07). - ^ Archives of the Caml mailing list > Message from Xavier Leroy. [2021-09-10]. (
原始 内容 存 档于2022-03-31). - ^ Functory. [2021-08-30]. (
原始 内容 存 档于2022-01-20). - ^ ocamlnet/Plasma. [2021-08-30]. (
原始 内容 存 档于2022-03-23). - ^ OCaml - The toplevel system or REPL (ocaml). ocaml.org. [2021-05-17]. (
原始 内容 存 档于2021-09-11). - ^ Batch compilation (ocamlc) (页面
存 档备份,存 于互联网档案 馆). - ^ Object types. [2021-09-10]. (
原始 内容 存 档于2022-03-10). - ^ Coq(页面
存 档备份,存 于互联网档案 馆) - ^ Flow: A Static Type Checker for JavaScript. [2021-08-29]. (
原始 内容 存 档于2022-04-08). - ^ Infer static analyzer. [2021-08-29]. (
原始 内容 存 档于2022-05-12). - ^ GitHub - facebook/pyre-check: Performant type-checking for python.. 9 February 2019 [2021-08-29]. (
原始 内容 存 档于2022-05-05) –通 过GitHub. - ^ WebAssembly/spec: WebAssembly specification, reference interpreter, and test suite.. World Wide Web Consortium. 5 December 2019 [2021-05-14]. (
原始 内容 存 档于2022-05-12) –通 过GitHub. - ^ FFTW(页面
存 档备份,存 于互联网档案 馆) - ^ MirageOS. [2021-08-29]. (
原始 内容 存 档于2022-04-20). - ^ Unison. [2021-08-28]. (
原始 内容 存 档于2021-07-12).