写完这段代码之后
module type TS = sig
type +'a t
end
module T : TS = struct
type 'a t = {info : 'a list}
end
Run Code Online (Sandbox Code Playgroud)
我意识到我需要info变得可变.
我写道,然后:
module type TS = sig
type +'a t
end
module T : TS = struct
type 'a t = {mutable info : 'a list}
end
Run Code Online (Sandbox Code Playgroud)
但是,出乎意料,
Type declarations do not match:
type 'a t = { mutable info : 'a list; }
is not included in
type +'a t
Their variances …Run Code Online (Sandbox Code Playgroud) Reason ML优于JavaScript的一个优点是它提供了Map一种使用结构相等而不是引用相等的类型.
但是,我找不到这个用法的例子.
例如,我如何声明一个scores字符串映射到整数的类型?
/* Something like this */
type scores = Map<string, int>;
Run Code Online (Sandbox Code Playgroud)
我将如何构建一个实例?
/* Something like this */
let myMap = scores();
let myMap2 = myMap.set('x', 100);
Run Code Online (Sandbox Code Playgroud) 假设我有一个具有以下结构的简单项目:
\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune-project\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 bin\n \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune\n \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main.ml\nRun Code Online (Sandbox Code Playgroud)\ndune-project
(lang dune 2.7)\n(name myproject)\n\n(package\n (name myproject)\n (synopsis "myproject")\n (description "Basic project")\n)\nRun Code Online (Sandbox Code Playgroud)\ndune
(executable\n (name main)\n (public_name myproject)\n)\nRun Code Online (Sandbox Code Playgroud)\n编译时,我有一个具有以下结构的dune build新目录:_build
_build\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 default\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune-project\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 META.myproject\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 myproject.dune-package\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 myproject.install\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 src\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.exe\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 main.ml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 install\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 default\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 bin\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 myproject -> ../../../default/src/bin/main.exe\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 myproject\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 dune-package -> ../../../../default/myproject.dune-package\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 META -> …Run Code Online (Sandbox Code Playgroud) 好吧,这主要是关于好奇心,但我发现它太奇怪了.
我们假设我有这个代码
sig.mli
type t = A | B
Run Code Online (Sandbox Code Playgroud)
main.ml
let f =
let open Sig in
function A | B -> ()
Run Code Online (Sandbox Code Playgroud)
如果我编译,一切都会工作.
现在,让我们尝试修改 sig.mli
sig.mli
type t = A | B
exception Argh
Run Code Online (Sandbox Code Playgroud)
和 main.ml
main.ml
let f =
let open Sig in
function
| A -> ()
| B -> raise Argh
Run Code Online (Sandbox Code Playgroud)
让我们尝试编译它:
> ocamlc -o main sig.mli main.ml
File "main.ml", line 1:
Error: Error while linking main.cmo:
Reference to undefined global `Sig'
Run Code Online (Sandbox Code Playgroud)
好吧,是不是因为我添加了例外?也许这意味着异常就像函数或模块一样,需要适当的实现.
但是,如果我写的话怎么办?
main.ml
let …Run Code Online (Sandbox Code Playgroud) 我实际上不确定这对 monad 是否可行,或者是否应该用它们来完成,并且我正在寻找解决方案,而不是用 monad 解决它(如果 monad 不是解决方案)。
假设我有以下代码(经过简化,但想法就在这里):
module IM = Map.Make (Int)
let f k v m =
if IM.mem k m then (m, true)
else (IM.add k v m, false)
let a =
let m = IM.empty in
let m, res = f 0 "Zero" m in
if res then
let m, res = f 1 "One" m in
if res then f 2 "Two" m else (m, res)
else (m, res)
Run Code Online (Sandbox Code Playgroud)
我重复了好多次:
let value, boolean = function …Run Code Online (Sandbox Code Playgroud) 假设我写了这个函数:
let f ?(x=0) fmt y = Format.fprintf fmt "%d" (x+y)
Run Code Online (Sandbox Code Playgroud)
它的类型是: ?x:int -> Format.formatter -> int -> unit
我可以指定x或不指定.
现在,让我们这样称呼它:
let () = Format.printf "%a@." f 0
Run Code Online (Sandbox Code Playgroud)
我有这个错误:
Error: This expression has type ?x:int -> Format.formatter -> int -> unit
but an expression was expected of type Format.formatter -> 'a -> unit
Run Code Online (Sandbox Code Playgroud)
好吧,我不明白为什么这会是一个问题.参数是可选的,如果我不说它应该没问题,不是吗?(写作 Format.printf "%a" (f ~x:0) 0 很明显,但有可选参数的意义何在?)
我的意思是,如果我声明我的函数是这样的:
let f ?(x=0) () fmt y = Format.fprintf fmt "%d" (x+y)
Run Code Online (Sandbox Code Playgroud)
它的类型是:?x:int -> () -> …
我想了解ocaml中迭代器,枚举和序列之间的区别
enumeration:
type 'a t = {
mutable count : unit -> int; (** Return the number of remaining elements in the enumeration. *)
mutable next : unit -> 'a; (** Return the next element of the enumeration or raise [No_more_elements].*)
mutable clone : unit -> 'a t;(** Return a copy of the enumeration. *)
mutable fast : bool; (** [true] if [count] can be done without reading all elements, [false] otherwise.*)
}
sequence:
type 'a node =
| Nil …Run Code Online (Sandbox Code Playgroud) 假设我有这样的架构:
\n\n.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Cargo.lock\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Cargo.toml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.rs\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rsc/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file.xml\nRun Code Online (Sandbox Code Playgroud)\n\n我想在每次运行时加载file.xml以填充一些表。为此我可以写:
.\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Cargo.lock\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 Cargo.toml\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 src/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 main.rs\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 rsc/\n\xe2\x94\x82 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 file.xml\nRun Code Online (Sandbox Code Playgroud)\n\n但如果我不从 运行程序,相对路径将不起作用src。
我可以执行以下操作:
\n\nuse std::fs::File;\nuse std::path::Path;\n\nfn open<P: AsRef<Path>>(path: P) {\n let _ = File::open(path).unwrap();\n println!("file opened");\n}\n\nfn main() {\n open("../rsc/file.xml");\n}\nRun Code Online (Sandbox Code Playgroud)\n\n但这将在编译时完成,这意味着更改file.xml意味着重新编译程序,因此在可维护性方面完全不安全。
我可以看到的另一个选项是将rsc路径作为我的程序的参数,但我发现它有点麻烦,因为这不是一个可选参数,我真的需要知道我的rsc目录在哪里,并且我知道我的板条箱将具有这种架构。
有什么我看不到的吗?
\n\n我看到这篇文章:如何避免 Rust 中的硬编码值
\n\n但我的问题总结在这一部分:
\n\n\n\n\n如果您正在部署二进制文件,则可能必须提供应用程序应找到其资源的路径。
\n
而且没有其他的精确性。
\n我尝试在 Ocaml 中的类型级别上实现 Peano 算术,但遇到了一个问题:
module Nat = struct
type zero = Z
type 'a succ = S
type 'a nat = Zero : zero nat | Succ : 'a nat -> 'a succ nat
end
Run Code Online (Sandbox Code Playgroud)
现在,如果我想实现add,关于此操作的两个公理是:
我试过
let rec add : type n1 n2. n1 nat -> n2 nat -> 'a nat =
fun a b -> match b with Zero -> a | Succ b' -> Succ (add a b')
Run Code Online (Sandbox Code Playgroud)
但
9 | fun a b …Run Code Online (Sandbox Code Playgroud) 我只想有一个在 Hashtbls 上通用的简单函数,所以我写了这个:
let iter_htbl (type a) (module H : Hashtbl.S with type key = a) htbl =
H.iter (fun _key _v -> ()) htbl
Run Code Online (Sandbox Code Playgroud)
这给了我以下错误:
53 | H.iter (fun _key _v -> ()) htbl
^^^^
Error: This expression has type 'a but an expression was expected of type
'b H.t
The type constructor H.t would escape its scope
Run Code Online (Sandbox Code Playgroud)
如果我写:
53 | H.iter (fun _key _v -> ()) htbl
^^^^
Error: This expression has type 'a but an expression was …Run Code Online (Sandbox Code Playgroud) 这是一个悬而未决的问题,但我从未设法找到令我高兴的解决方案.
假设我有这种代数数据类型:
type t = A of int | B of float | C of string
Run Code Online (Sandbox Code Playgroud)
现在,假设我想写一个compare函数 - 因为我想把我的值放在一个Map例子中 - 我会像这样写:
let compare t1 t2 =
match t1, t2 with
| A x, A y -> compare x y
| A _, _ -> -1
| _, A _ -> 1
| B x, B y -> compare x y
| B _, _ -> -1
| _, B _ -> 1
| C x, C …Run Code Online (Sandbox Code Playgroud) 我的Quicksort代码适用于N的某些值(列表大小),但对于较大的值(例如,N = 82031),OCaml返回的错误是:
致命错误:异常Stack_overflow.
我究竟做错了什么?
我是否应该创建一个迭代版本,因为OCaml不支持大值的递归函数?
let rec append l1 l2 =
match l1 with
| [] -> l2
| x::xs -> x::(append xs l2)
let rec partition p l =
match l with
| [] -> ([],[])
| x::xs ->
let (cs,bs) = partition p xs in
if p < x then
(cs,x::bs)
else
(x::cs,bs)
let rec quicksort l =
match l with
| [] -> []
| x::xs ->
let (ys, zs) = partition x xs in
append …Run Code Online (Sandbox Code Playgroud) 我想执行此代码,但我有这个错误.OCaml中是否存在相互递归?
错误:未绑定值quicksort您的意思是tquicksort?
我的问题:
let rec tquicksort lm l lM =
match l with
| [] -> unirL(unir (rev lm) lM)
| lx::lxs -> let (la, lb) = part lx lxs in
if nroelem la < nroelem lb then
tquicksort (quicksort (la::lm)) lb lM
else
tquicksort lm la (quicksort (lb::lM));;
let quicksort l = tquicksort [] l [];;
Run Code Online (Sandbox Code Playgroud) ocaml ×12
covariance ×1
dictionary ×1
exception ×1
fatal-error ×1
file ×1
invariance ×1
module ×1
monads ×1
ocaml-dune ×1
polymorphism ×1
reason ×1
reasonml ×1
recursion ×1
rust ×1
signature ×1