Standard ML快餐教程(1) - 初识

简介: 如何搭建Standard ML开发环境,以及如何在sml中生存下来

Standard ML快餐教程(1) - 初识

好久没写快餐教程了,下面开始一个新的系列,关于函数式编程语言的系列。打算写三种语言:Standard ML,ocaml和Haskell。
这几门语言都不是新贵了,其中Standard ML的知名度可能最低。因为ML系列的影响力,其实我们已经从新的语言如rust等中学到过这些老语言的很多知识了。现在我们可能只要将它们还原回去就好。

运行环境

Standard ML,顾名思义,是ML语言的一种标准规范,主要的版本有SML 90和SML 97。
标准的实现就有很多种方式。比如以交互式编译为主要特点的SML/NJ,还有以优化编译为主要目标的mlton。另外一个重要的Standard ML编译器是剑桥大学的David Matthews开发的poly/ML,因为著名的推理证明工具Isabelle是使用polyml开发的。

SML/NJ是由贝尔实验室的David MacQueen和普林斯顿大学的Andrew Appel于1986年发起的。为了满足1997年SML的修订,1998年1月推出了110版本。时至2020年,主版本号还是110,比如我现在用的版本是v110.97。

SML/NJ的项目主页在:http://www.smlnj.org/。其源代码是使用svn管理的。mlton和polyml的源代码都在github上管理。mlton的地址为:https://github.com/MLton/mlton,ployml的地址为:https://github.com/polyml/polyml/

安装的话,因为以上三种语言工具都属于比较通用成熟的工具,在mac上的homebrew和Ubuntu之类的主流Linux发布版本中都有支持。
比如在macOS上,可以使用homebrew进行安装这三种环境:

brew install mlton
brew install polyml
brew cask install smlnj

在Ubuntu下可以使用下面的命令安装:

apt install smlnj
apt install mlton
apt install polyml

安装好之后,运行sml命令,就可以进入sml/nj的交互式环境,就可以开始学习编写Standard ML代码了,"-"是smlnj的提示符:

Standard ML of New Jersey v110.79 [built: Sat Oct 26 12:27:04 2019]
-

我们可以先写个HelloWorld程序练练手,比如叫hello.sml:

val a = 1 :int ;
print "Hello,World\n";

smlnj可以通过sml hello.sml来调用。
也可以通过mlton hello.sml来编译,然后会生成hello,运行hello就可以看到运行结果。

使用polyc进行编译的时候,会报下面的错误:

poly: : error: Value or constructor (main) has not been declared
Found near PolyML.export (List.nth (CommandLine.arguments (), 3), main)
Static Errors

这是因为polyml需要一个main函数。
我们写个main函数吧:

fun main() = print "Hello,World\n";

然后调用polyc去编译:

polyc hello2.sml -o hello2

最后运行hello2就可以看到运行结果。

polyml也可以通过poly命令交互式运行。

Poly/ML 5.8.1 Release

提示符为">"。

数据类型

我们可以通过交互式界面来了解下基本数据类型的用法。

数字类型

比如我们输入一个整数1:

> 1;
val it = 1: int

我们可以看到,这样一个整数被赋给一个叫it的默认变量,其类型为int.

-1在Standard ML中表示为"~1",我们来看下:

> val a = 0 - 1;
val a = ~1: int

符点数是real类型:

> val b = 1e8;
val b = 100000000.0: real

字符串

Standard ML支持字符串类型:

> val d = "Hello";
val d = "Hello": string

布尔值

Standard ML使用true和false两个关键字来表示bool类型:

> true;
val it = true: bool
> false;
val it = false: bool
> 1>0;
val it = true: bool

空值

Standard ML的空类型为unit,用来表示一个空表():

> ();
val it = (): unit
> val g = ();
val g = (): unit

同样,空的记录也是unit:

> val x3 = {};
val x3 = (): unit

字符类型

通过“#”,也可以描述char类型:

> val e = #"c";
val e = #"c": char

ord函数用来将字符转成整数,chr相反将ASCII值转成字符。

> val x4 = ord(#"a");
val x4 = 97: int
> val x5 = chr(65);
val x5 = #"A": char

数据结构

元组

元组是使用括号描述的列表。类型将成为几个类型之乘积。
比如(3.0, true)的类型是real * bool.

> val x6 = (3.0, true);
val x6 = (3.0, true): real * bool

列表

不同于元组,列表的元素必须是相同的,用方括号表示。
空列表不是unit,也是个列表类型。

- val a1 = [];
val a1 = [] : 'a list

只要类型相同就可以,元组也没问题:

- val a2 = [1,2];
val a2 = [1,2] : int list
- val a3 = ["h","e"];
val a3 = ["h","e"] : string list
- val a4 = [(3,4),(2,5)];
val a4 = [(3,4),(2,5)] : (int * int) list

记录

类似于哈希表的一种结构,指定key与value:

- val a5 = {name="xulun",age=20};
val a5 = {age=20,name="xulun"} : {age:int, name:string}

如果以数字1,2,3等为key,则建立的记录就是元组。我们看个例子:

- val a7 = {1=true, 2=3.0};
val a7 = (true,3.0) : bool * real

多赋值

Standard ML支持模式匹配多赋值,比如我们使用变量元组和值元组,举个例子看下就清楚了:

> val (x1,x2) = (1.0, true);
val x1 = 1.0: real
val x2 = true: bool

语句

函数

可以通过fun来定义函数,我们直接看个求平方的例子:

> fun s2 (x:int):int = x*x;
val s2 = fn: int -> int
> s2(4);
val it = 16: int

可以不指定类型,由系统进行推断:

- fun add1 x y = x + y;
val add1 = fn : int -> int -> int

如果想用浮点类型,可以指定一个,其它由系统推断:

- fun add2 (x:real) y = x + y;
val add2 = fn : real -> real -> real

注释

Standard ML使用(**)来写注释。

条件语句

Standard ML支持if then else语句,如果if为真则返回then后面的表达式,否则返回else分支的结果。

- fun neg1 (x:int) : bool = if x < 0 then true else false;
val neg1 = fn : int -> bool

还记得-1在sml表示为~1吧,我们测试下上面的if判断:

- neg1(1);
val it = false : bool
- neg1(~1);
val it = true : bool

case语句

通过case语句,可以处理多分支的条件,每个条件进行自己的匹配。格式为case x of x1 => something1 | x2 => something2 | ...

我们来看个例子:

- fun grade1(x:int) = case x of 0 => false | 1 => true | x => false;
val grade1 = fn : int -> bool
- grade1(1);
val it = true : bool
- grade1(0);
val it = false : bool
- grade1(100);
val it = false : bool

标准库

做为一种标准语言,Standard ML也支持可移植性的标准库。我们可以调用这些库像其它语言一样愉快地编程了。sml的标准库叫做BASIS。
第一次调用的时候,basis会被加载进来:

- Char.isUpper(#"a");
[autoloading]
[library $SMLNJ-BASIS/basis.cm is stable]
[library $SMLNJ-BASIS/(basis.cm):basis-common.cm is stable]
[autoloading done]
val it = false : bool

再来几个例子,比如计算实数的绝对值:

- Real.abs(~1.5);
val it = 1.5 : real

整数转实数:

- val a10 = Real.fromInt(1);
val a10 = 1.0 : real

求平方根:

- val a11 = Math.sqrt(2.0);
[autoloading]
[autoloading done]
val a11 = 1.41421356237 : real

字符串连接:

- val a11 = String.concat(["Hello","World"]);
val a11 = "HelloWorld" : string

一起看起来都不错。类型,分支,函数等都有了。还有强大的标准库,恭喜你,已经在Standard ML的世界里活下来了 :)

目录
相关文章
|
12月前
|
机器学习/深度学习 编解码 人工智能
7 Papers & Radios | MIT深度学习框架登Nature封面;2010年以来,ML算力需求增100亿倍(1)
7 Papers & Radios | MIT深度学习框架登Nature封面;2010年以来,ML算力需求增100亿倍
|
12月前
|
机器学习/深度学习 编解码 人工智能
7 Papers & Radios | MIT深度学习框架登Nature封面;2010年以来,ML算力需求增100亿倍(2)
7 Papers & Radios | MIT深度学习框架登Nature封面;2010年以来,ML算力需求增100亿倍
|
12月前
|
自然语言处理
kaggle比赛——Jigsaw Rate Severity of Toxic Comments(NLP类型)——分析获奖模型笔记
kaggle比赛——Jigsaw Rate Severity of Toxic Comments(NLP类型)——分析获奖模型笔记
|
机器学习/深度学习 算法 数据挖掘
cs224w(图机器学习)2021冬季课程学习笔记16 Community Detection in Networks
本章主要内容: 本章首先介绍了网络中社区community(或cluster / group)的概念,以及从社会学角度来证明了网络中社区结构的存在性。 接下来介绍了modularity概念衡量community识别效果。 然后介绍了Louvain算法1识别网络中的community。 对于overlapping communiteis,本章介绍了BigCLAM2 方法来进行识别。
cs224w(图机器学习)2021冬季课程学习笔记16 Community Detection in Networks
|
机器学习/深度学习 资源调度 并行计算
李宏毅2021春季机器学习课程视频笔记1:Introduction, Colab & PyTorch Tutorials, HW1
李宏毅2021春季机器学习课程视频笔记1:Introduction, Colab & PyTorch Tutorials, HW1
李宏毅2021春季机器学习课程视频笔记1:Introduction, Colab & PyTorch Tutorials, HW1
|
机器学习/深度学习 自然语言处理 搜索推荐
cs224w(图机器学习)2021冬季课程学习笔记20 Advanced Topics on GNNs
本章主要内容: 本章首先介绍了在此之前学习的message passing系GNN模型的限制,然后介绍了position-aware GNN1 和 identity-aware GNN (IDGNN)2 来解决相应的问题。 最后介绍了GNN模型的鲁棒性问题。
cs224w(图机器学习)2021冬季课程学习笔记20 Advanced Topics on GNNs
|
机器学习/深度学习 算法 测试技术
cs224w(图机器学习)2021冬季课程学习笔记2: Traditional Methods for ML on Graphs
cs224w(图机器学习)2021冬季课程学习笔记2: Traditional Methods for ML on Graphs
cs224w(图机器学习)2021冬季课程学习笔记2: Traditional Methods for ML on Graphs
|
机器学习/深度学习 人工智能 搜索推荐
cs224w(图机器学习)2021冬季课程学习笔记1 Introduction; Machine Learning for Graphs
cs224w(图机器学习)2021冬季课程学习笔记1 Introduction; Machine Learning for Graphs
cs224w(图机器学习)2021冬季课程学习笔记1 Introduction; Machine Learning for Graphs
|
API 索引 Python
ML之catboost:catboost的CatBoostRegressor函数源代码简介、解读之详细攻略
ML之catboost:catboost的CatBoostRegressor函数源代码简介、解读之详细攻略
|
机器学习/深度学习 PyTorch Go
330+ 个机器学习模型/库探索工具!Papers With Code 重磅推出!
330+ 个机器学习模型/库探索工具!Papers With Code 重磅推出!
254 0
330+ 个机器学习模型/库探索工具!Papers With Code 重磅推出!