使用 Dune 编译和调试 OCaml 代码

news/2024/10/6 21:38:24/文章来源:https://www.cnblogs.com/sysss-blogs/p/18449116

下载 Dune

opam install dune

创建项目

dune init project <project-name>

如果创建成功,有

Success: initialized project component named <project-name>

得到如下的一个文件结构

project_name/
├── dune-project
├── test
│   ├── dune
│   └── test_project_name.ml
├── lib
│   └── dune
├── bin
│   ├── dune
│   └── main.ml
└── project_name.opam
/lib

lib 里存放编写的库 library(可以看作是一组模块 module 的集合),比如我有如下的一个 module MyModule

(* MyModule.ml *)
type t = int listlet init n = List.init n (fun i -> i)let print l = List.iter print_int l

把它放在 lib 下后修改 /lib/dune 文件如下:

(library(name my_project)(modules MyModule))

/bin/main.ml 下可以这么调用:

let lst = My_project.MyModule.init 10let () = My_project.MyModule.print lst

library 描述文件 stanza 的格式如下:

(library(name <library-name>)<optional-fields>)

<library-name> 指库 library 的名字,在上面的例子中,<library-name>my_project,那么在 /bin/main.ml 中就是用 My_project 去调用它内部的模块。

<optional-fields> 有很多可选项,包括:

  • (modules <modules>) 规定哪些模块 module 被包括在这个库 library 之中,使用 Ordered Set Language 来描述

  • (libraries <libraries-dependencies>) 决定了库 library 的依赖

/bin

/bin 存放可运行的 .ml 代码文件,关于 module 的调用方式见上文,使用 dune exec <project_name> 在终端中执行代码,上面的例子的运行结果如下:

dune exec my_project                                                                                                        ─╯
Hello, World!
0123456789

如果想要引入外部库,可以修改 /bin/dune,以使用 lwt 库为例:

(executable(public_name myproject)(name main)(libraries myproject lwt.unix))
(* main.ml *)let lst = Myproject.MyModule.init 10let () = Myproject.MyModule.print lst;Lwt_main.run (Lwt_io.printf "Hello, world!\n")

再次调用 dune exec 可以发现其正常工作

dune-project

dune-project 是描述工程 project 的元数据文件,以我刚刚建立的工程为例:

(lang dune 3.6) ; dune 的版本(name my_project) ; 工程名(generate_opam_files true)(source(github username/reponame))(authors "Author Name") ; 作者(maintainers "Maintainer Name") ; 拥有者(license LICENSE) (documentation https://url/to/documentation)(package(name my_project)(synopsis "A short synopsis")(description "A longer description")(depends ocaml dune)(tags(topics "to describe" your project))); See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project

构建测试

根据 github 更新时间来看,推荐使用 QCheck 或者 ppx_inline_test

使用 QCheck 构建随机单元测试

Cornell cs3110 的课程中使用的是 QCheck,在我的 docker 容器上不是很能正确安装

一直报错 Curl failed

原因是 seq 这个依赖对应的地址没能被正确 dns 解析,把 dns 服务器地址改为 8.8.8.8 之后问题被修复( 有点难绷

QCheck 文档

使用 QCheck 的例子如下:

#require "qcheck"(* [rev] is a function that reverses a list. For example, [rev [1;2;3]] is [3;2;1]. *)
let rev lst = List.rev lst(* QCheck *)
let test =QCheck.Test.make ~count:1000 ~name:"test_rev"QCheck.(list small_nat)(fun l -> rev l = l);;(* we can check right now the property... *)
QCheck_runner.run_tests [test];;
#require "qcheck"let leap_year year =if year mod 400 = 0 then trueelse if year mod 100 = 0 then falseelse year mod 4 = 0let test =QCheck.Test.make ~count:1000 ~name:"test_leap_year_and_mod_4"QCheck.(small_nat)(fun year -> leap_year year = (year mod 4 = 0));;QCheck_runner.run_tests [test]

集成到 Dune 中:

(executable(public_name myproject)(name main)(libraries myproject lwt.unix qcheck))

使用 OUnit2 测试套件

(施工中)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/809217.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解异常和中断(Cortex-M3)

异常和中断的深入了解对于调试很有用,也非常有助于对RTOS的理解,本文是阅读Cortex-M3权威指南和ST、ARM的技术文档,总结出比较精炼的文档。中断一般是由硬件(如外设和外部输入引脚)产生的事件。异常一般指CPU内部产生的打断。但是,也可以把中断称为一种异常我们一般称为系…

深入理解异常和中断

异常和中断的深入了解对于调试很有用,也非常有助于对RTOS的理解,本文是阅读Cortex-M3权威指南和ST、ARM的技术文档,总结出比较精炼的文档。系统异常和外部中断中断一般是由硬件(如外设和外部输入引脚)产生的事件。异常一般指CPU内部产生的打断。但是,也可以把中断称为一种…

ch被动扫描学习

在渗透测试中,被动扫描就像斥候一样担任前驱搜查的任务,帮助后续的渗透攻击等的深入推进提供十分重要的信息。当然,正如一双锐利的眼和好的侦查工具是一名优秀侦察兵的标配,在进行渗透测试的时候,优秀的搜索引擎就是信息收集者的”夜行衣”和“望远镜”。借助它们我们可以…

Nuxt.js 应用中的 app:suspense:resolve 钩子详解

title: Nuxt.js 应用中的 app:suspense:resolve 钩子详解 date: 2024/10/6 updated: 2024/10/6 author: cmdragon excerpt: app:suspense:resolve 是一个强大的钩子,允许开发者在异步数据解析完成后的最后一步执行必要的处理。通过合理使用该钩子,我们可以优化组件的渲染…

多校A层冲刺NOIP2024模拟赛02 csp-s模拟9

多校A层冲刺NOIP2024模拟赛02 四道题因为暑假被拉去当模拟赛 暑假集训CSP提高模拟22 了,遂直接把赛后代码交了上去,然后就被通知换题了。 原 \(100+100+100+20\) 被在 accoders NOI 上被卡成了 \(100+100+90+10\) ,更改 long long 和 int 后达到了 \(100+100+100+30\) 。 \(…

败者树、置换选择排序、最佳归并树

败者树败者树用一个数组即可实现,而且,上图中的那些方块所代表的结点是不存储在败者树中的置换选择排序 置换选择排序的目的是构造出比工作区更长的初始归并段,而更长就意味着初始归并段会更少,可能会减少归并的趟数,进而减少读写磁盘次数来优化排序时间。 置换选择排序的…

Codeforces Rund 977 div2 个人题解(A~E1)

Codeforces Rund 977 div2 个人题解(A,B,C1,C2,E1) Dashboard - Codeforces Round 977 (Div. 2, based on COMPFEST 16 - Final Round) - Codeforces 火车头 #define _CRT_SECURE_NO_WARNINGS 1​#include <algorithm>#include <array>#include <bitset>#inc…

ide启动多个实例

ide启动多个实例 方法一: ide 2022.X及之后 Run=> Edit Configurations=> 选中项目=> “Build and run”栏=> Modify Options=> 选中“Allow multiple instances”然后就可以run多次项目了 但是要主要改端口 方法二: 先把项目打包,然后启动多个terminal,每个…

周鸿祎:用这10条打造你的完美的商业计划书(附详细讲解)

转载:周鸿祎:用这10条打造你的完美的商业计划书(附详细讲解)_产品 (sohu.com) 江湖上流传着一篇“360大佬周鸿祎版10页商业计划书PPT”,高屋建瓴的讲述了BP制作框架,很有价值。诚然,一个形式上外观精美,具有上有吸引力的BP让人赏心悦目,但更重要的还是有实实在在的内容…

DiLiGenT光度立体数据集

本文对DiLiGenT光度立体数据集进行了详细介绍。简介 ”DiLiGenT“ 光度立体数据集,全称为 calibrated Directional Lightings, objects of General reflectance, and ‘ground Truth’ shapes (normals),即使用标定过的定向光源,对一些具有常见反射率特性的物体进行光度立体…

Pool Kings All In One

Pool Kings All In One 泳池之王 Pool Kings - Mountain Paradise / 泳池之王 - 山间天堂 Utah waterfall MountainPool Kings All In One泳池之王demosPool Kings - Mountain Paradise / 泳池之王 - 山间天堂Utah waterfall Mountainhttps://vimeo.com/233842674 https://www.…

CHT

水电费是否收到fwe】今天探索一下CTH的电脑 PEPPA PIG放映室!tm的图怎么死了