我是OCaml的初学者.我想知道如何在单独的文件中定义相互递归的数据类型.
我知道以下程序是合法的.
type t1 = A of int | B of t2
and t2 = C of float | C of t1
Run Code Online (Sandbox Code Playgroud)
现在,我想这个定义t1并t2在可读性其他文件(因为被需要来逐个很多util的功能).
我也知道,我可以定义t1并t2通过使作为上述.mli文件和隐藏实现细节(只写type t1和type t2在.mli文件).
但是,现在我不想隐藏它们.有谁知道怎么做?
我希望简单的解决方案(不使用复杂或魔术......).
我在以以下方式执行fork时遇到麻烦,因为子进程返回a Core_kernel.Std.never_returns,而父进程试图返回()。
我得到了错误This expression has type unit but an expression was expected of type Core_kernel.Std.never_returns = Core_kernel.Nothing0.t。似乎找不到使用的正确方法Core.Std。
open Core.Std
open Unix
let () =
let prog = "ls" in
let args = ["ls"; "-l"] in
match Unix.fork () with
| `In_the_child ->
Unix.exec ~prog:prog ~args:args ();
| `In_the_parent _ ->
(* continue on with the program *)
Run Code Online (Sandbox Code Playgroud) 我正在尝试实现一个在 OCaml 中返回阶乘的函数,但我不知道我是否实际上使用了连续传递样式:
let fact n =
let rec factorial n cont = match n with
| 0 -> cont ()
| _ -> factorial (n-1) (fun () -> cont () * n) in
factorial n (fun () -> 1)
Run Code Online (Sandbox Code Playgroud)
在我看来,我并没有真正延迟计算,而只是替换了代码中的计算。
我正在学习OCaml,我对变量的不变性感到困惑.根据我正在阅读的书,变量是不可改变的.到目前为止一切都那么好,但为什么我可以这样做:
let foo = 42
let foo = 4242
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
我有几个模块实现相同的接口.我想根据命令行中给出的一个参数只加载该模块中的一个.
我在考虑使用一流的模块,但问题是我想在模块实例化之前执行一些功能.
目前我有这个:
module Arch = (val RetrolixAbstractArch.get_arch() : RetrolixAbstractArch.AbstractArch)
let get_arch () =
let arch = Options.get_arch() in
if arch = "" then
Error.global_error "During analysis of compiler's architecture"
"No architecture specified"
else
if arch = "mips" then
( module MipsArch : AbstractArch)
else
Error.global_error "During analysis of compiler's architecture"
(Printf.sprintf "Architecture %s not supported or unknown" arch)
Run Code Online (Sandbox Code Playgroud)
但由于命令行尚未解析,请Options.get_arch给我空字符串.
我想在执行此函数之前实现命令行解析(不在函数中添加解析).可能吗 ?我应该找到另一种方法来实现这一目标吗?
如果我有一个元组的输入,其中包含两个相同长度的整数列表,并且我希望我的输出是这两个列表的压缩列表,那么从元组中提取这两个列表后,如何将每个单独的元素压缩为一个列表?例如,如果我的输入是twolists= ([1;2;3], [4;5;6]),那么我希望我的输出是[(1,4); (2,5); (3,6)]。如何压缩每个元素并将其添加到我的输出中?函数名称和类型如下:
let rec pairlists twolists = ...
val pairlists : 'a list * 'b list -> ('a * 'b) list = fun
Run Code Online (Sandbox Code Playgroud)
到目前为止我有:
let rec pairlists twolists =
let (l1, l2) = twolists in
let rec zip (l1,l2) =
match l1 with
|[] -> l2
|x :: xs -> x :: zip(l2, xs) in
twolists ;;
Run Code Online (Sandbox Code Playgroud)
但这显然不是我想要的。
在OCaml中,是否可以在模式匹配时将名称绑定到数据构造函数的内容?作为一个说明性示例,假设我有以下OCaml程序:
type t = A of int * int | B of int * int
let sum_pair (a, b) = a + b
let f x = match x with
| A (a1, a2) -> sum_pair (a1, a2)
| B (_, b) -> b
let _ = Printf.printf "%d\n" (f (A (1, 2)))
Run Code Online (Sandbox Code Playgroud)
这会编译,但是我需要(a1, a2)在匹配后重新构建元组以将其传递给相当烦人sum_pair!相反,我希望能够写作
let f x = match x with
| A (_ as pair) -> sum_pair pair
| B (_, b) -> b …Run Code Online (Sandbox Code Playgroud) 所以这是附加两个列表的一种方法:
let rec append l1 l2 =
match l1 with
| h :: t -> h :: append t l2
| [] -> l2
Run Code Online (Sandbox Code Playgroud)
但我正在尝试编写一个尾递归版本的追加.(在调用递归函数之前解决问题).
到目前为止这是我的代码,但是当我尝试在第一个if语句中添加append时,代码因为奇怪的原因而出错.
let list1 = [1;2;3;4]
let list2 = [5;6;7;8]
let rec append lista listb =
match listb with
| h :: taillist -> if taillist != [] then
begin
lista @ [h];
(* I cant put an append recursive call here because it causes error*)
end else
append lista taillist;
| [] -> lista;;
append …Run Code Online (Sandbox Code Playgroud) 我试图获得一个函数(作为参数给出一个集合)来返回一个集合,其元素是从主集合形成的所有子集.例如:{1; 2; 3} - > {{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3}}
但是我并不完全知道如何创建一个允许我使用一组集合的模块.我应该将它定义为什么类型?
我有一个(string * int) list元素列表,我需要找到最大的int元素并返回相应的(string * int)元素。
我有这样的atm,但问题是,我认为我的方法更多是“典型编程”
let it = [] in
for x = 0 to length LIST - 1 do
let str = ((List.nth LIST x).string) in
let num = ((List.nth LIST x).int) in
let it = it @ [num, str] in
let (str, num) = List.hd(List.rev it) in
[str, num]
Run Code Online (Sandbox Code Playgroud)
我想做的是循环遍历列表,并将字符串和int值添加到另一个列表中,然后对其进行排序,反转,然后使用head(应该是最大int),然后我需要返回该对 (string * int)
ocaml ×10
list ×3
module ×2
recursion ×2
command-line ×1
first-class ×1
max ×1
pairing ×1
set ×1
types ×1