有没有办法将哈希表转换为OCaml中的(键,对)值列表?
我知道,给定哈希表ht我们可以做到
BatList.of_enum (BatHashtbl.enum ht)
Run Code Online (Sandbox Code Playgroud)
使用电池库.这会将表转换为枚举,然后将枚举转换为列表.但我正在寻找一种不使用电池库的解决方案.在标准的OCaml Hashtbl模块中,似乎没有一种方法可以将对提取为列表或将其功能组合以实现此目的的方式.有什么建议?
任何人都可以解释这个OCaml顶级行为吗?
# 1________________________________1;;
- : int = 11
Run Code Online (Sandbox Code Playgroud)
(大行是一系列下划线:'_')
出于好奇,这个程序也在ocamlc下编译.
作为枚举集合的更大问题的一部分,我需要编写一个OCaml函数'choose',它接受一个列表并输出作为由该列表的元素组成的所有可能的大小为k的序列的列表(不重复序列,可以通过排列获得彼此).它们放在结束列表中的顺序无关紧要.
例如,
choose 2 [1;2;3;4] = [[1;2];[1;3];[1;4];[2;3];[2;4];[3;4]]
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
我想让整个事情变得懒惰,输出一个懒惰的列表,但是如果你有一个严格的解决方案,那也将非常有用.
ocaml functional-programming lazy-evaluation list-manipulation
关于OCaml记录,我有一个非常基本的问题.假设我有一个定义的记录:
type r = {a:int;b:int;c:int}
let x = {a=3;b=8;c=2}
Run Code Online (Sandbox Code Playgroud)
现在,假设我想要创建一个新记录,其中所有字段都等于x但c = 4.我可以写:
let y = {a=3;b=8;c=4}
Run Code Online (Sandbox Code Playgroud)
但这很烦人,因为不需要重写a = 3和b = 8.我也可以写:
let y = {a=x.a;b=x.b;c=4}
Run Code Online (Sandbox Code Playgroud)
但如果记录有很多字段,这仍然不好.有没有办法写一些像:
let y = {x with c=4}
Run Code Online (Sandbox Code Playgroud)
或类似的东西?
非常感谢您的帮助.
一切顺利,Surikator.
很抱歉这个问题很长.我决定首先解释问题的背景,因为我的问题可能有其他解决方案.如果你赶时间,请阅读下面的问题.
(编辑 - 同时我添加了一些解决问题的尝试.第四个有我的最终结论,你可以直接跳到它.)
上下文
我有一个哈希表,大约有20k对(key(i),value(i)).我想生成像这样的随机列表
[(key(213),value(213));(key(127),value(127));(key(89),value(89));...]
Run Code Online (Sandbox Code Playgroud)
限制是,一旦我选择了键(213)作为列表的第一个元素,并不是所有键都可以跟随它(我有一些其他函数'决定',它可以决定某个键是否可以是下一个键.列表与否).所以,我想选择一个随机的下一个元素并检查它是否合适 - 在上面的例子中选择了key(127).如果该元素被我的'决定'功能拒绝,我想随机选择另一个.但是我不想选择同样被拒绝的因为我知道它会被再次拒绝而且不仅效率低下,如果只有几个键可以成为下一个键,我也会冒风险,需要很长时间直到找到合适的钥匙.注意,可以重复,例如
[(key(213),value(213));(key(213),value(213));(key(78),value(78));...]
Run Code Online (Sandbox Code Playgroud)
这是可以的,只要'decision'函数接受键(213)作为列表中的下一个.因此,我需要的是一种随机枚举哈希表中的(键,值)对的方法.每当我必须选择一个键时,我创建一个枚举,我通过使用'decision'函数检查每个新元素来消耗(因此,不会发生重复),当我找到一个时,我将它添加到列表中并继续递增列表.问题是我不希望每次哈希表的枚举都相同.我希望它是随机的.(这与我在特定问题中搜索空间的结构有关,这与我的相关性无关.)
我当然可以通过生成随机整数和仅使用列表来实现这一点 - 这就是我目前正在做的事情.但是,由于这是我经常遇到的问题,我想知道是否在某处有一些随机的枚举工具用于哈希表.
问题
哈希表是否有某些随机枚举函数?我知道函数BatHashtbl.enum(电池库),但我认为它总是会给我相同的哈希表相同的枚举(这是正确的吗?).此外,BatHashtbl模块中似乎没有任何类型的东西.我会对类似的东西感兴趣
random_enum: ('a, 'b) t -> int -> ('a * 'b) Enum.t
Run Code Online (Sandbox Code Playgroud)
当提供哈希表和一些整数作为随机生成器的种子时,它将给出哈希表的不同随机枚举.有任何想法吗?
谢谢你的帮助!
最好的,Surikator.
第一次尝试
在Niki在评论中提出建议并通过电池库查看更多细节后,我想出了这个
let rand_enum ht n =
BatRandom.init n;
let hte = BatHashtbl.enum ht
in let s = BatRandom.shuffle hte (* This returns*)
in Array.to_list s
Run Code Online (Sandbox Code Playgroud)
哪种类型
val rand_enum : ('a,'b) BatHashtbl.t -> int -> ('a*'b) list
Run Code Online (Sandbox Code Playgroud)
它使用Fisher-Yates算法进行在O(n)中运行的混洗.它返回一个列表而不是枚举,这很烦人,因为这意味着即使我对使用rand_enum获得的列表的第三个元素感到满意,该函数仍然会计算整个20k元素的随机枚举.哈希表.
最好的,Surikator
第二次尝试
我将模块RndHashtblEnum定义为
(* Random Hashtable Enumeration …Run Code Online (Sandbox Code Playgroud) 我想编写一个OCaml函数,它接受一个URL并返回一个由该位置的HTML文件内容组成的字符串.有任何想法吗?
非常感谢!
最好的,Surikator.
我遇到的一个问题是将两个模块的类型和值带入一个新的组合模块.我举个例子.目前我有以下两种类型的签名
module type Ordered =
sig
type t (* the type of elements which have an order *)
val eq : t * t -> bool
val lt : t * t -> bool
val leq : t * t -> bool
end
module type Stack =
sig
exception Empty
type 'a t (* the type of polymorphic stacks *)
val empty : 'a t
val isEmpty : 'a t -> bool
val cons : 'a * 'a t …Run Code Online (Sandbox Code Playgroud) 我有一个大型OCaml项目,我正在使用ocamlbuild进行编译.一切正常,我有一个伟大的可执行文件,可以按我的要求完成所有操作.问题是,当我把原生可执行文件"my_prog.native"运行到其他地方(不同的机器使用相同的操作系统等)时,新机器抱怨它找不到洋甘菊(用于电池)库我正在使用).我认为我们从ocamlbuild得到了可执行文件是独立的,不需要的OCaml或甘菊存在于我们跑了机器,但似乎并不如此.
关于如何制作真正的独立可执行文件的任何想法?
我想为我正在编写的OCaml应用程序构建一个GUI.我的第一个想法是使用GTK +.我希望我的应用程序可以在Mac,Linux,Windows上运行,具有自然的外观和感觉.我知道,虽然GTK +默认在Mac上使用X11(看起来很糟糕),但有gtk-osx-application使用石英,看起来很自然,我刚刚使用macport安装.
我有三个问题:
(1)实际上是否可以gtk-osx-application +quartz+no_x11与OCaml 一起使用?(我之前的GODI安装(基于x11的gtk2到位)安装了lablgtk2没有问题,现在(gtk-osx-application +quartz+no_x11以及之前基于x11的gtk2被删除)抱怨找不到/opt/local/lib/libgtk-x11-2.0.0.dylib,这与x11相关.但是,就我而言知道,当通过GODI安装lablgtk2时,没有办法在x11上选择石英.)
(2)如果我使用gtk-osx-application在我的Mac上开发代码,我可以在其他使用不同GTK的平台上使用代码进行编译,还是会带来问题?
(3)如果它确实带来了问题,你是否知道在OCaml中开发GUI的任何其他环境可能对外观和感觉都很好并且仍然可以很容易地交叉使用?(我知道labltk,但我更喜欢具有更多功能的东西,例如,能够使用笔记本,也就是标签面板,并且能够使用Glade进行快速GUI设计.)
谢谢你的帮助!
干杯,Surikator
我有一个计算密集的OCaml应用程序,我希望它在后台运行而不会干扰正常的计算机使用.我想向用户提供两个选项:
(1)应用程序仅在CPU使用率几乎为0%时运行;
(2)应用程序仅使用"免费"处理能力(例如,如果其他进程加起来为100%,则OCaml应用程序暂停;如果其他进程几乎为0%,则对OCaml应用程序没有限制;如果其他进程添加比如说,50%然后OCaml将使用高达50%).
我的想法是检查代码中各个检查点的CPU使用情况,并在必要时暂停执行.
在(1)中,我们只检查CPU是否低于2%,如果不是,则暂停直到它再次低于2%.
在(2)中,事情比较棘手.由于当没有限制时,应用程序总是消耗100%的CPU,检查点将非常频繁,将CPU使用率降低到一半,我只需要在每个检查点将其延迟到检查点之间的时间.如果检查点频繁,这就类似于使用50%的CPU,我会说.对于其他百分比,我们可以通过暂停适当的时间段来做类似的事情.然而,这看起来非常人为,充满了开销,最重要的是,我不确定它是否真的能满足我的需求.更好的替代方法是Unix.nice n在应用程序开始时使用一些适当的整数调用.我想这个设置n=15可能是正确的.
(Q1)如何从我的OCaml应用程序中了解应用程序进程的CPU使用情况?(我想用OCaml函数执行此操作,而不是通过在命令行上调用"ps"或类似的东西...)
(Q2)你认为我的想法存在问题(2).改变流程的优点有哪些实际差异?
(Q3)您对(2)有任何其他建议吗?
(以下问题涉及OCaml语言并且在OCaml中有示例,但问题非常普遍,对于任何其他计算机语言来说,正确答案也可能解决我的问题.所以,只需用您最喜欢的语言来假设这个问题.)
我想编写一个函数,它将OCaml中的任意程序作为字符串,并决定程序是正确还是不正确,在后一种情况下,我是否可以通过在最后连接适当的字符使其成为正确的程序.
我假设有一个语言的编译器,我可以应用它并得到一个回复,说"编译"或"不编译 - 错误在第X行,字符Y"(大多数情况下)语言无论如何).总之,我想有一个函数,它接受一个程序并返回:
例如,OCaml程序let x = f不正确,因为f它在使用时尚未定义.它不能继续,因为你在f之后写的东西总是一些以前没有定义过的标识符.该程序let x =也是不正确的; 但如果我们延伸到let x = 5那时我们有一个完全有效的程序.所以,我的函数应该在第一种情况下返回Erroneous而在第二种情况下返回Incomplete.
如果我们有这个计划,事情可能会变得棘手
let ans = 5
let x = a
Run Code Online (Sandbox Code Playgroud)
因为我的功能必须要看到如果我继续该程序,ns那么程序就变得正确了.
我的问题是:你认为有可能编写这样的函数/算法吗?如果是这样,那么一般的想法是什么?如果没有,试着说服我,事实并非如此.
(我会对任何见解或部分答案感到满意,例如暗示不完整的东西.例如,我相信如果语言编译器说第3行有错误并且程序有100行,那么就没有可能继续该计划.)
compiler-construction ocaml programming-languages compiler-theory
我已经定义了两个模块类型和两个模块
module type FOO = sig type e end
module type BAR = sig type t end
module Foo : FOO = struct type e = int end
module Bar : BAR = struct type t = int end
Run Code Online (Sandbox Code Playgroud)
然后我将一个仿函数定义为
module Fun (F:FOO) (B:BAR with type t = F.e) = struct type x = string end
Run Code Online (Sandbox Code Playgroud)
(这是一个玩具示例,请忽略这一事实F和B不使用的算符)
现在,如果我定义模块
module Bla = Fun (Foo) (Bar)
Run Code Online (Sandbox Code Playgroud)
我明白了
Error: Signature mismatch:
Modules do not match:
sig type t = …Run Code Online (Sandbox Code Playgroud)