当前位置: 首页 > 工具软件 > ocaml-jupyter > 使用案例 >

Ocaml学习笔记

周超英
2023-12-01
Ocaml学习笔记
Ocaml中标准的数据类型:
整型(type int):1,2,-2
字符型(type char):'a','\n','\x48'
字符串(type string):"ocaml"
布尔型(type bool):true,false
浮点型(type float):1.2,5.3
类型转换:
整型转换为字符串:string_of_int 1;;
整型转换为浮点型:float_of_int 2;;
算术表达式:
1+1;;
布尔表达式:
ture&&false;;与
not false;;非
true||false;;或
字符串操作符:
"hello" ^ "world";;字符串连接符“^”
通过字符串下标引用字符串中的字母:
"abc".[1];;
char='b';;
浮点型操作操作符后面要加点".":
1.2+.1.3;;
变量定义与调用:
let x=1;;定义变量
x;;引用变量
PS:变量名的首字母是小写字母;变量不能被修改


本地变量定义;
定义为本地变量:
let average =
let sum=10+42+3 in 
sum/3
;;
sum;;
sum是局部变量;
一次定义多个变量:
let a=1 and b =2;;
let result=
let c=1 and d=2 in 
c+d;;
列表:不能被修改;变量长度;
数组:能被修改;能随机取数
表定义:首字母:the head;另一个表的尾:the tail;
1.空表
[];;
2.带有一个元素的列表:
1::[];;
3.带有两个元素的表:
1::(2::[]);; 或者 1::2::[];;
表的连接:
[12;13]@ [5;6];;
列表长度:
List.length['q';'5';'hj'];;
随机取数:
List.nth['a';'b';'c'] 1;;取出数组中的第二个元素
PS:表中所有元素类型一致


数组定义:
let a=[|1;2;3|];;
取数:
a.(1);;
数组能被修改:
a.(1)<-5;;把数组中的第二个元素修改为5;
a;;输出所有数组元素


函数中的参数用空格分开:
cos 0.0;;
atan 1.0 1.0;;
用let关键字给函数定义:
let 函数名 参数1 参数2 ...=
expression
例如:
let sum x y z=x+y+z;;
sum 1 3 2;;


一个函数调用本身用关键词:let rec 


函数作为返回值:
函数被当做参数;;
函数能被当做返回值;


List.map 函数 表;
例如:
List.map string_of_int [1;2;3];;输出表中元素并被转换为英文;


函数定义可以不带有名字
fun argument1 argument2 ... ->expression
当函数小而且只被用一次是很方便:
List.map(fun x->x*1)[1;2;3];;
通过创建元组:一个组里有多重类型的变量:
(,."ocaml");;
let x=('e',true,[1;2]);;
抽取值:
let a,b,c=x;;


函数可以用元组作为参数:
let average pair=
let (x,y)=pair in
(x+y)/2;;
使用:
average(2,8);;


用一个元组一个函数可以返回多个值:
let div x y=
  let q=x/y in 
  let r=x-q*y in
  (q,r);;
使用:
div(20,4);;


定义一个新的数据类型:
type day_of_week=
|Sunday
|Monday
|Tuesday
|Wednesday
|Thursday
|Friday
|Saturday #首字母大写
使用其中的枚举类型:
Sunday


用一个函数返回数字的天数:
let number_of_day day=
if day=Sunday then 
0
else if day=Monday then
1
else if day=Tuesday then
2
else if day=Wednesday then
3
else if day=Thursday then
4
else if day=Friday then
5
else
assert false #给出错误报告
;;
如果我们忘了一个case,当程序运行时会给出错误报告:
number_of_day Satruday;;
用匹配模式可以做上述函数相同的事:
let number_of_day_with_match day=
  match day with
  |Sunday->0  #如果day为Sunday返回0
  |Monday->1
  |Tuesday->2
  |Wednesday->3
  |Thursday->4
  |Friday->5
  |Saturday->6
  ;;
当我们缺失一个Case时,Ocaml能够探测出来:
let number_of_day_with_match day=
  match day with
  |Sunday->0  #如果day为Sunday返回0
  |Monday->1
  |Tuesday->2
  |Wednesday->3
  |Thursday->4
  |Friday->5
  ;;
  枚举类型的元素可以有参数:
  type figure=
  |Vertex
  |Circle of float
  |Rectangle of float * float #“*”为连接符不是操作运算符
  ;;
 例如:
 Circle 1.0;;
 Renctangle(2.0,3.0);;
 计算上边定义的枚举类figure的大小:
 let pi=4. * .atan 1.0
 let size figure=
    match figure with 
|Vertex->0
|Circle radius->pi*.radius *.radius
|Rectangle(a,b)->a*.b
;;
预定义代数类型:option
type 'a option=
|None
|Some of 'a
;;
例子:
#Some 42;;
-:int option =Some 42


列表可以定义成如下:
type 'a list=
|Nil
|Cons of 'a * 'a list
用[]和::符号比上述方法更方便


匹配模式可以用在列表:
match | with #"|"是表类型的参数
  |[]->...#表为空,获取什么结果
  |x:: |->...#如果原表为“list”,那么x就是原表的第一个元素,“|”代表出去原表第一个元素的子表
  
  练习:编写一个求表中元素(整型)总和的函数:
 let rec match_size x=
   match x with
   | []->0
   |a::b->a+match_size(b);;#使用迭代函数:每次拿表中的第一个元素相加
 结构体类型中的值可以有多种类型:
 type color ={
red:int;
green:int;
blue:int;
 };;
PS: 结构体中元素的名字开始要用小写字母
结构体中的元素初始化可以通过制定构建:
let c={red=255;green=0;blue=90};;
获取结构体元素的值可以通过点符号:
c.red;;
修改结构体中的指定元素:
{c with green=128};;


结构体中能通过mutable标志修改初始化之后结构体中的元素:
type counter={
mutable value:int;
};;
例如:
let c={value=0};;
c.value<-42;;#把初始化之后的c中value元素的初始值修改为“42”
c.value;;#查看修改之后的结果
Ocaml中有一个预定义类型:ref
type 'a ref={mutable contents:'a};;


ref类型操作:
创建:let x=ref 0;;
使用:!x;;
修改:x:=3;;


逻辑等于的比较符:=
比较文本中的两个值:
1=1;;
["a";"b"]=["a";"c"];;
算术等于:==
["a"]==["a"]


匹配模式可以用在除了函数以外的所有类型:
match x with 
 |0->(* case for x=0 *)#两个"*"为注释文本
 |1->(* case for x=1 *)
 |_->(* case for all other values of x *)
 
match Sys.os_type with
|"Win32"->(* case for Window *)
|"Unix"->(* case for Unix *)
|other->(* case for all other operating systems *)


匹配模式能过元组同时匹配多个值:
match(a,b) with
 |(42,"foo")->...
 |(34,"bar")->...
 ...
一个运算可能在任何时候中断在出现异常的时候:
List.assoc "b" [("a",1);("b",2)];;
List.assoc "x" [("a",1);("b",2)];;
List.assoc key:在表中查询元组中与key联系的值.。
 
用raise函数来抛出异常:
raise Not_found;;
带有参数的异常:
raise(Failure "something went wrong");;


用try..with来获取异常:
try
...
with
|pattern1->
...
|pattern2->
...
...
用关键字exception定义异常:
exception Error
exception Error2 of int*string
异常只是一种扩展的代数数据类型。


























  



















 类似资料: