ocaml学习
来源:互联网 发布:屏幕亮点修复软件 编辑:程序博客网 时间:2024/05/01 16:52
安装
Linux环境下
# apt-get install ocaml# apt-get install ledit# apt-get install tuareg-mode
Windows环境下
自行下载OCamlWinPlus
- 《Practical OCaml》, Joshua B. Smith
- 官方文档
- 教程网站
笔记
一、注释
# (*comment*)
二、let给表达式的结果赋一个名字
1. 使用let定义一个整型:
# let inchesPerMile = 12*3*1760;;val inchesPerMile : int = 63360
2. 使用let定义一个函数:
# let cube (x:int) = x*x*x;;val cube : int -> int = <fun>
# let square x = x *. x;;val square : float -> float = <fun>3. 多个参数:
# let sumsq (x:int) (y:int) = x*x + y*y;; val sumsq : int -> int -> int = <fun>
ocaml里的类型检查和判断是自动完成的
三、布尔型true和false
1. not方法:
# not (5=10);;- : bool = true
2. 条件表达式 if xx then xx else xx:
# if true then (3*5) else (5-2);;- : int = 15
三、浮点数float
浮点方法:
# 1. +. 2.1;;- : float = 3.1
# 2.3 *. -3.5;;- : float = -8.04999999999999893(*注意比较“+.”和“+”*)
需要注意的是,形如 1 + 1.0 或是 1 +. 1.0之类的运算都是会报错的,这时候需要用到类型转换函数type_of_type:
# 1 + 1.0;;Error: This expression has type float but an expression was expected of type int# 1 +. 1.0;;Error: This expression has type int but an expression was expected of type float# float_of_int 1 +. 1.0;;- : float = 2.
ocaml最基础的数据类型有如下几种(来源)
- int 在32位处理器上是31位的,64位处理器上是63位的,剩下的一位做了回收机制的flag。不过要是非想要c的效果,可以使用ocaml在Nativeint模块中提供的nativeint类型。同样的,uint也可以使用nativeint模仿
- bool true,false
- char 8位的字符,不支持utf-8和unicode
- string "Hello world"
- float ieee标准的双精度浮点数,不支持单精度浮点数
- unit 这个是很有意思的一个数据类型,写作(),用于制作序列运算,具体可以参照tpl书上的做法
ocaml基础的操作符:
- + 整型加法
- - 整型减法
- ~-或- 整型负
- * 整型乘法
- / 整型除法,若除零则会raise一个Division_by_zero
- mod 整型同余,若第二个参数为0则会raise一个Division_by_zero
- land 整型的逐位逻辑与
- lor 整型的逐位或
- lxor 整型的逐位异或
- lsl 整型的逻辑左移
- lsr 整型的逻辑右移
- asr 整型的算数右移
- +. 浮点加法
- -. 浮点减法
- ~-.或-. 浮点负
- *. 浮点乘法
- /. 浮点除法
- ** 浮点乘方
- @ 列表连结
- ^ 字符串连结
- ! 取引用
- := 引用赋址
- = 结构意义上的相等
- <> 结构意义上的不相等
- == 物理意义上的相等
- != 物理意义上的不相等
- < 小于
- <= 不大于
- > 大于
- >= 不小于
- && 布尔与
- || 布尔或
其中比较有意思的一个是结构意义上的相等和物理意义上的相等的区别。官方文档里给出了这样两段话:
e1 = e2 tests for structural equality of e1 and e2. Mutable structures (e.g. references and
arrays) are equal if and only if their current contents are structurally equal, even if the two
mutable objects are not the same physical object. Equality between functional values raises
Invalid_argument. Equality between cyclic data structures may not terminate.
e1 == e2 tests for physical equality of e1 and e2. On mutable types such as references,
arrays, strings, records with mutable elds and objects with mutable instance variables, e1
== e2 is true if and only if physical modi cation of e1 also a ects e2. Onnon-mutable
types, the behavior of ( == ) is implementation-dependent; however, it is guaranteed that
e1 == e2 implies compare e1 e2 = 0.
这个模块里常见的除了上面列举出来的,还有pred,succ,min,max,compare,raise,sin,abs,log,exp等等,篇幅所限就不写了。
四、递归函数
rec标识:
# let rec fact(n:int) = if n = 0 then 1 else n * fact(n-1);;val fact : int -> int = <fun>
五、列表
1. 元素类别必须相同:
# [1;2;3;];;- : int list = [1; 2; 3]
# [];;- : 'a list = []
2. 从前方追加元素,::读作"cons",是右结合的:
# 1::[2;3];;- : int list = [1; 2; 3]
# 1::2::3::[];;- : int list = [1; 2; 3]
3. 使用List模块中的List.hd和List.tl操纵列表元素:
# List.hd [1;2;3];;- : int = 1
# List.tl [1;2;3];;- : int list = [2; 3]
4. 一些例子:
1) 尾部追加元素
# let rec snoc(l:int list)(x:int)= if l=[] then x::[] else List.hd l :: snoc(List.tl l) x;;val snoc : int list -> int -> int list = <fun># snoc [5;4;3;2] 1;;- : int list = [5; 4; 3; 2; 1]
2) 倒置元素
# let rec revaux(l:int list)(res:int list)= if l=[] then res else revaux (List.tl l) (List.hd l :: res);;val revaux : int list -> int list -> int list = <fun># revaux [1;2;3][4;5;6];;- : int list = [3; 2; 1; 4; 5; 6]# let rev(l:int list) = revaux l [];;val rev : int list -> int list = <fun># rev [1;2;3;4;5];;- : int list = [5; 4; 3; 2; 1]
3) 重写递归为tail-recursive style
原递归:
# let rec fact(n:int)= if n=0 then 1 else n*fact(n-1);;val fact : int -> int = <fun>
重写:
# let rec factaux(acc:int)(n:int)= if n=0 then acc else factaux(acc*n)(n-1);;val factaux : int -> int -> int = <fun># let fact(n:int)=factaux 1 n;;val fact : int -> int = <fun>
recursion style在返回后不需要进行计算
六、元组
1. 元素之间类型无限制:
# ("children",[3.1;2.5]);;- : string * float list = ("children", [3.1; 2.5])
# let cube (x:int) = x*x*x;;val cube : int -> int = <fun># (cube,"cube");;- : (int -> int) * string = (<fun>, "cube”)
2. 注意区分:
# let g(x,y) = x*y;;val g : int * int -> int = <fun>
# let g(x:int)(y:int) = x*y;;val g : int -> int -> int = <fun>
七、模式匹配
1. 基本形式match xx with xx a->b,若不能完整覆盖该类型则会报warning:
val fact : int -> int = <fun># let rec listSum(l:int list)= match l with []->0 | x::y-> x + listSum y;;val listSum : int list -> int = <fun>
2. 通配符 _:
# let rec fact(n:int)= match n with 0->1 | _ -> n*fact(n-1);;val fact : int -> int = <fun>
# let lastName name= match name with (n,_,_)->n;;val lastName : 'a * 'b * 'c -> 'a = <fun>
八、多态
‘a类型:
# let rec length l = match l with [] -> 0 | _::y -> 1 + length y;;val length : 'a list -> int = <fun>
九、异常
1. 定义一个exception,注意首字母大写:
# exception NegNum;;exception NegNum
2. raise使用异常:
# let rec fact n = if n<0 then raise NegNum else if n=0 then 1 else n*fact(n-1);;val fact : int -> int = <fun># fact (-3);;Exception: NegNum.
十、in
let … in e;;等价为
# let … ;;# e;;
1. 本地函数
# let rec loop (n:int)= if n=1 then 1 else n*loop(n-1) in loop 10;;- : int = 3628800# loop 2;;Error: Unbound value loop
2.简单的split实现
# let split l = let rec loop w l = match l with []->[w] | (' '::ls) -> w::(loop [] ls) | (c::ls) -> loop (w @ [c]) ls in loop [] l;;val split : char list -> char list list = <fun>(*其中@操作是List.append的简写*)
3. split另一种实现
# let split l = let rec loop w l= match w,l with _,[] -> [w] | _,(' '::ls)->w::(loop [] ls) | _,(c::ls)->loop (w@[c]) ls in loop [] l;;val split : char list -> char list list = <fun>(*和例子2的效果完全相同,会在多个空格时产生空列表*)
4. 排除空列表的split实现
# let better_split l = let rec loop w l = match w,l with [],[]->[] | _,[]->[w] | [],(' '::ls) -> loop [] ls | _,(' '::ls) -> w::(loop [] ls) | _,(c::ls) -> loop (w@[c]) ls in loop [] l;;val better_split : char list -> char list list = <fun>
- ocaml学习
- Ocaml学习笔记 语句
- 学习Ocaml(2)---基础
- 学习ocaml----(3)基础
- Ocaml学习笔记
- ocaml学习随笔-1
- ocaml
- OCaml
- 学习Ocaml--(1)基本概念
- Ocaml学习笔记 标识符和简单数据类型
- Ocaml学习笔记 算术和逻辑运算符
- 学习OCaml---(0)环境安装
- Practical OCaml
- ocaml 2
- OCaml安装
- OCaml语言学习笔记(一)——Introduction to Objective Camel
- OCaml学习笔记(二)——Introduction to Objective Camel
- Ocaml 入门整理2
- Linux编译Windows共享目录下代码
- Android 通过Base64上传图片到服务器
- 使用ajax后,target失效,弹出新窗口
- 开源物理引擎
- Eclipse 使用配置记录
- ocaml学习
- 北风网课程开放下载第一季
- 第十讲 对象编程简介(实例补充)
- Launcher源码浅析-----涉及Workspace界面资源加载重要类和资源文件简介
- loongson 1B 开发板移植sqlite3.6.20
- 40个有创意的jQuery图片和内容滑动及弹出插件收藏集之一
- 黑马程序员--用类加载器的方式管理资源和配置文件
- linux 打印错误的简单方法
- JVM1:概述