Rust有一个线性类型系统。在OCaml中是否有任何(好的)模拟方法?例如,当使用ocaml-lua时,我想确保只有当Lua处于特定状态(堆栈顶部的表等)时才会调用某些函数。
Edti :这是最近一篇关于与该问题相关的资源多态性的论文:https://arxiv.org/abs/1803.02796
答案 0 :(得分:8)
正如John Rivers所建议的那样,您可以使用monadic风格来表示
“有效”计算以隐藏线性约束的方式
效果API。下面是类型('a, 'st) t
的一个示例
用于表示使用文件句柄(其标识为
将隐式/未说出以保证它不会被复制
产生类型为'a
的结果,并将文件句柄保留在状态中
'st
(幻像类型是“开放”或“关闭”)。你必须使用
monad¹的run
实际上做了什么,它的类型确保
文件句柄在使用后正确关闭。
module File : sig
type ('a, 'st) t
type open_st = Open
type close_st = Close
val bind : ('a, 's1) t -> ('a -> ('b, 's2) t) -> ('b, 's2) t
val open_ : string -> (unit, open_st) t
val read : (string, open_st) t
val close : (unit, close_st) t
val run : ('a, close_st) t -> 'a
end = struct
type ('a, 'st) t = unit -> 'a
type open_st = Open
type close_st = Close
let run m = m ()
let bind m f = fun () ->
let x = run m in
run (f x)
let close = fun () ->
print_endline "[lib] close"
let read = fun () ->
let result = "toto" in
print_endline ("[lib] read " ^ result);
result
let open_ path = fun () ->
print_endline ("[lib] open " ^ path)
end
let test =
let open File in
let (>>=) = bind in
run begin
open_ "/tmp/foo" >>= fun () ->
read >>= fun content ->
print_endline ("[user] read " ^ content);
close
end
当然,这只是为了让你体会到它的风格 API。有关更严肃的用途,请参阅Oleg的monadic regions示例。
您可能也对研究编程语言感兴趣 Mezzo,旨在 是ML的变体,具有更细粒度的状态控制(和相关的 有效的模式)通过线性分类学科与分离 资源。请注意,它现在只是一项研究实验,而不是 实际上是针对用户。 ATS也很重要, 虽然最终少了ML。 Rust可能实际上是合理的 这些实验的“实用”对应物。
¹:它实际上不是monad,因为它没有return
/ unit
组合子,但重点是强制类型控制的排序,就像monadic bind
运算符一样。但它可以有一个map
。