首页 > 代码库 > ocaml学习

ocaml学习

ocaml与haskell一样,是functional programming的代表。

对于有一定编程经验的人来说,入手一种新语言,最有效的方式就是开发一些实用的utility,因此top-level肯定不能满足我们的需要。

对于ocaml来说,我们怎样才能生成一个命令行程序的PE文件呢?

 

先安装OPAM

参考:https://github.com/realworldocaml/book/wiki/Installation-Instructions

$ add-apt-repository ppa:avsm/ppa
$ apt-get update
$ apt-get install curl build-essential m4 ocaml opam

 

参考:

http://zh.wikibooks.org/wiki/User:Gqqnb/OCaml%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B/%EF%BC%88%E4%B8%80%EF%BC%89%E7%AE%80%E4%BB%8B

 

let ratio x y =
    Float.of_int x /. Float.of_int y;;
 
val ratio : int -> int -> float = <fun>

下面一行是ocaml编译器给出的函数模型,

因为ocaml中将function视为一种value,因此会有val ratio,代表ratio是一个value.

:后面表示的是value的类型,可见这个value的类型,是将一个int转化成另外一个int,再将新的int转化成float,这似乎与我们定义的逻辑不符合,但是事实是,ratio x y 可以被视为

val ratio1 : int -> int = <fun>
val ratio2 : int -> float = <fun>
let ratio x y = 
    (ratio1 x) y

而(ratio1 x)本身返回就是一个function,因为function可以看作是value,所以可以被返回。

而(ratio1 x)返回的函数正是(ratio2).

 

tuple

let tuple_a = (3, "Three");;
 
val tuple_a : int * string = (3, "Three")

这里面对于tuple的类型给出的是用*连接的,*代表笛卡尔积,因为tuple可以是所有int和string类型的笛卡尔积。

 

pattern-matching

比如,我们知道有一个tuple是两个元素的,就可以使用(x, y)这种方式来提取其中的内容,这就是pattern-matching.

 

tuple vs list

tuple用于表示固定数目的不同类型元素的组合;

list用于表示任意数目的同种类型元素的组合。

 

tuple的元素之间用,来间隔,

而list的元素之间用;来间隔。

 

labeled argument

贴上了标签的参数,比如~f,这样可以使用名称而不是pos来标识参数。

 

list pattern-matching

[]和::用于list的元素中的模式匹配,这种匹配是左提取的。

 

match xxx with | | |匹配

类似于C++中的switch

 

recursive list functions

里面有两种case:

base case,

inductive case。

 

这类似于数学中的数学归纳法。

 

 

options

代表着一些参数可以存在,也可以不存在。

Some和None是创建optional value的构造函数。

 

然后可以通过

match option with
| Some x –>
| None –>
 

来检查option的值,并且根据情况作出处理。

 

如果指明类型时,某个类型是option,必须显式指明。

比如, 一个tuple,其中第一个允许是option

string option * string

 

Pervasives模块

默认每个ocaml程序都会打开这个模块。

 

let以及value的作用域

顶层的let是global作用的,而let里面的let是local的,而且必须配合in使用。

 

定义数据结构records

type point2d = {x:float ; y:float};;

可以使用下面三种pattern-matching来提取record中的元素

let func_a {x = x_pos; y= y_pos} =
    x_pos + y_pos;;
 
let func_b { x;y } =
    x + y;;
 
let_func_c v1 v2 = 
    v1.x + v2.x;;

 

variant type

变种类型,提供了不同实现类型在逻辑上的聚合。

可以理解为基类的抽象。

type shape =
    | Circle of circle_imp
    | Rect of rect_imp
    | Triangle of triangle_imp;;

然后可以通过

match shape_a with
    | Circel cir -> ...
    | Rect rect -> ...
    | Triangle tri -> ... ;;

来执行不同的操作。

 

这与option很相似。