3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MLAdvent Calendar 2020

Day 5

OCaml Upcoming Changes 2020: Allow to name existentials in pattern-matching

Posted at

この記事はML Advent Calendar 2020 5日目の記事です。

OCamlにそろそろ入りそうな機能を紹介します。

今回は、Allow to name existentials in pattern-matching by garrigue · Pull Request #9584 · ocaml/ocaml を紹介します。


OCamlでは(他の言語でも同じように?)、言語機能が追加されたときに、処理系は正しく型づけするが、ユーザーが項の型を書けなかったり、かなりまわりくどい書き方をしないと型を明示できないことがたまに起こる。過去に第一級モジュールが追加されたときにも、何かユーザーがうまく型を書けないケースがあったような気がする(あやふや)。

今回紹介するAllow to name existentials in pattern-matching by garrigue · Pull Request #9584 · ocaml/ocamlは、パターンマッチ時にGADTで導入される存在型を参照するための構文を追加する。

具体例で説明しよう。

OCamlには存在型を扱う構文がふたつある。

ひとつはモジュールで、「ある型tと、その値value」をシグネチャで表現すると次のようになる。

module type S = sig
  type t
  val value : t
end

もうひとつはGADTで、同様のものを表現すると次のようになる。

type t = Value : 'a -> t

前者から後者への変換は簡単で、次のような関数で書ける。

let module s_to_t (module M : S) = Value M.value

逆はけっこう面倒だ。

単純に考えると次のようになりそうだが、これは型チェッカーに文句を言われる。

let t_to_s = function
  | Value (v : 'a) ->
    (module struct
      type t = 'a
      let value = x
    end : S)
(*
11 |   | Value (v : 'a) ->
               ^^^^^^^^
Error: This pattern matches values of type 'a
       but a pattern was expected which matches values of type $Value_'a
       The type constructor $Value_'a would escape its scope
*)

これは、 v の型は Value の分岐でしか使えないはずなのに、 'afunction 全体がスコープになることが原因だ。

今はこんな風に書く必要がある。

let t_to_s = function
  | Value v ->
    let f (type a) (x : a) =
      (module struct
        type t = a
        let value = x
      end : S)
    in
    f v

ここでは、一旦ローカル関数で局所抽象型 a を導入し、それを使って第一級モジュールをつくっている。

これはあまりにも面倒なので、Allow to name existentials in pattern-matching by garrigue · Pull Request #9584 · ocaml/ocamlでは、次のように書ける構文を導入する。

let t_to_s = function
  | Value (type a) (v : a) ->
    (module struct
      type t = a
      let value = x
    end : S)

ちょうど、最初のプログラムと局所抽象型を使ったプログラムの間の子のような感じで、GADTで導入される存在型を (type a) の形でバリアントタグのあとに書けるようになる。

次のOCaml 4.12は既にfeature freezeされているので、この機能は4.13あたりで入るだろう。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?