OCaml 中的线性类型

2024-05-01

Rust http://www.rust-lang.org/有一个线性类型系统。有什么(好的)方法可以在 OCaml 中模拟这个吗?例如,当使用 ocaml-lua 时,我想确保仅当 Lua 处于特定状态(堆栈顶部的表等)时才调用某些函数。

Edit:这是最近一篇关于与该问题相关的资源多态性的论文:https://arxiv.org/abs/1803.02796 https://arxiv.org/abs/1803.02796

Edit 2:还有许多关于 OCaml 中会话类型的文章,包括提供一些语法糖的语法扩展。


正如 John Rivers 所建议的,您可以使用一元样式来表示 以隐藏线性约束的方式进行“有效”计算 效果API。下面是一个示例,其中类型('a, 'st) t是 用于表示使用文件句柄的计算(其身份是 隐式/不言而喻以保证它不能被复制),将 产品是类型的结果'a并将文件句柄保留在状态'st(幻像类型为“打开”或“关闭”)。你必须使用 这runmonad1 实际执行任何操作,其类型确保 文件句柄在使用后正确关闭。

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

(* starting with OCaml 4.13, you can use binding operators:
   ( let* ) instead of ( >>= ) *)
let test =
  let open File in
  let ( let* ) = bind in
  run begin
    let* () = open_ "/tmp/foo" in
    let* content = read in
    print_endline ("[user] read " ^ content);
    close
  end

当然,这只是为了让大家领略一下风格 API。对于更严重的用途,请参阅 Oleg 的单子的 地区 http://okmij.org/ftp/Haskell/regions.html例子。

您可能还对研究编程语言感兴趣Mezzo http://gallium.inria.fr/%7Eprotzenk/mezzo-lang/,其目的是 是 ML 的一个变体,具有更细粒度的状态控制(以及相关的 有效的模式)通过线性打字规则与分离 资源。注意,目前只是一个研究实验,不是 实际上是针对用户的。ATS http://ats-lang.org/也相关, 虽然最终不太像 ML。 Rust 实际上可能是合理的 这些实验的“实际”对应物。

1:它实际上不是一个单子,因为它没有return/unit组合器,但重点是强制类型控制排序作为单子bind操作员这样做。它可以有一个map, 尽管。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OCaml 中的线性类型 的相关文章

  • Ocaml 多态记录类型不太通用

    给定以下类型 type props state reactInstance props props state state updater event props state reactInstance gt event gt state
  • 在 OCaml 中读取 URL 的 HTML 内容

    我想编写一个 OCaml 函数 它接受一个 URL 并返回一个由该位置的 HTML 文件内容组成的字符串 有任何想法吗 多谢 最好的 苏里卡托 我已经使用 ocurl 和 nethtml 完成了这两件事 ocurl http sourcef
  • 什么时候应该在 OCaml 中使用对象?

    通常 OCaml 程序可以使用或不使用对象来编写 什么时候使用物品最有利 什么时候应该避免使用物品 作为一般经验法则 不要使用对象 它们带来的额外复杂性通常并不值得 我认为这也是适用于其他语言的规则 但那是另一回事了 至少对于 OCaml
  • 如何检查两个值是否是使用同一个构造函数创建的?

    假设我有 type t A of int B of int let xx A 2 let yy A 3 我想测试 xx 和 yy 的构造函数是否相等 是否有捷径可寻 而不必 match xx with A gt match yy with
  • F# 中的命令式多态性

    OCaml 的 Hindley Milner 类型系统不允许命令式多态性 类似于 System F 除非通过最近对记录类型的扩展 这同样适用于 F 然而 有时需要将用命令式多态性 例如 Coq 编写的程序翻译成此类语言 Coq 的 OCam
  • GADT 上的模式匹配失败

    我更多地使用 ReasonML 并发现了模式匹配type t从以下示例开始 无法处理该错误 错误 此模式与 t float 类型的值匹配 但需要一个与 t int 类型的值匹配的模式 float 类型与 int 类型不兼容 type t a
  • 让menhir将用户定义的函数从.mly添加到.mli

    Menhir 允许将任意 ocaml 代码添加到 mly 文件的末尾 我想在其中声明一些函数 但我找不到一种方法让 menhir 将我的函数添加到 mli 文件中 以便它们从其他模块中可见 是否可以 答案很简单 那就是no 中定义的代码 m
  • 跟踪编译器中 AST 节点的源位置 (ocaml)

    我正在使用 ocamllex yacc 在 ocaml 中编写编译器 一切进展顺利 但我遇到了设计问题 对于我创建的每个 AST 节点 最好能获得有关源代码中该节点的行 字符位置的信息 这对于稍后向用户提供错误消息很有用 现在 我可以向我的
  • 为什么这个 OCaml 程序比我的 C 程序更快?

    我写了一个基本的嬉皮舞 http www facebook com careers puzzles php puzzle id 7使用 C Python 和 OCaml 编写程序 诚然 这可能不是这三种语言的一个很好的基准 但我得到的结果是
  • OCaml 是否复制了自定义块?

    想象一下 我有一个名为 libcat 的 C 库 用于与我的毛茸茸的猫进行交互 因此 我正在为 OCaml 编写绑定来简化与 fluffy 的交互 module type CAT sig type cat val find gt cat v
  • 数据中的是什么?

    我使用OCaml版本4 02 3 我定义了一个类型self type self Self of self type self Self of self 及其实例s let rec s Self s val s self Self
  • OCaml 中的类型共享 - 类型检查器错误

    编译这个程序时 module type Inc sig type t val inc t gt t end module type Dec sig type t val dec t gt t end module Merger I Inc
  • 如何从ocaml列表中获取子列表

    我正在查看列表文档 图书馆好像没有提供sublist功能 我正在尝试从中获取元素列表i to j 现在我必须把它写成 let rec sublist list i j if i gt j then else List nth list i
  • 类型变量和局部抽象类型有什么区别?

    我试图理解的目的局部抽象类型在 OCaml 中 局部抽象类型与类型变量有何不同 看来他们有相同的行为 Type variable let f x a a x val f a gt a
  • 为什么 OCaml 不允许函数匹配? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • OCaml 中类型和模块相等的规则是什么

    我无法理解 OCaml 中模块的平等性 函子应该是适用的 这就是互联网所声称的 但这有时似乎会失败 而且我不太明白其背后的一般规则 这是我的示例代码 module type PT sig end module P struct end le
  • 链接“let”语句时使用“and”还是“in”更好?

    我意识到这可能是一个愚蠢的问题 但是 如果我把一堆let不需要需要了解彼此价值观的语句 使用是否更好and or in 例如 以下哪一个更可取 如果有 let a foo and b bar and c baz in etc or let
  • OCaml 中的不可变变量

    我正在学习 OCaml 我对变量的不变性有点困惑 根据我正在读的书 变量是不可变的 到目前为止一切顺利 但到底为什么我可以这样做 let foo 42 let foo 4242 我缺少什么 我认为最好的解释方法是举个例子 考虑以下代码 在
  • 将“列表”转换为“集合”?

    OCaml 真的没有从列表转换为集合的函数吗 如果是这样的话 是否可以制作一个通用函数list to set 我尝试制作一个多态集 但没有成功 基本问题 列表可以包含任何类型的元素 集合 假设你的意思是Set http caml inria
  • 使用fold_left/right反转OCaml中的列表

    更新 解决方案 感谢 jacobm 的帮助 我想出了一个解决方案 Folding Recursion let reverse list 3 theList List fold left fun element recursive call

随机推荐