7

Rustには線形型システムがあります。OCamlでこれをシミュレートする(良い)方法はありますか?たとえば、ocaml-luaを使用する場合、Luaが特定の状態(スタックの最上位のテーブルなど)にある場合にのみ一部の関数が呼び出されるようにしたいです。

編集:質問に関連するリソースポリモーフィズムに関する最近の論文は次のとおりです:https ://arxiv.org/abs/1803.02796

編集2:いくつかの構文糖衣を提供するための構文拡張を含む、利用可能なOCamlのセッションタイプに関する多くの記事もあります。

4

1 に答える 1

10

John Riversが提案しているように、モナディックスタイルを使用して、エフェクトAPIの線形制約を非表示にする方法で「効果的な」計算を表すことができます。以下は('a, 'st) t、ファイルハンドル(複製できないことを保証するためにIDが暗黙的/暗黙的)を使用して計算を表すために型が使用され、型の結果を生成し'a、ファイルハンドルを状態 'st(ファントム型)のままにする1つの例です。 「オープン」または「クローズ」のいずれか)。実際に何かを行うには、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のスタイルを味わうことだけを目的としています。より深刻な使用法については、オレグのモナディックリージョンの例を参照してください。

また、研究プログラミング言語Mezzoに興味があるかもしれません 。これは、分離されたリソースを使用した線形型付けの分野を通じて、状態(および関連する効果的なパターン)をよりきめ細かく制御するMLの変形を目指しています。これは現時点での調査実験であり、実際にはユーザーを対象としたものではないことに注意してください。ATSも関連性がありますが、最終的にはMLに似ていません。さびは、実際にはこれらの実験の合理的な「実用的な」対応物である可能性があります。

return¹: /コンビネータがないため、実際にはモナドではありませんが、重要なのは、モナド演算子unitのように型制御シーケンスを強制することです。bindしかし、それは持つことができmapます。

于 2013-03-26T06:43:59.687 に答える