2022/12/29

OCamlのlocally abstract typeといふもの

ファストクラスモジュール

このlocally abstract typeなるものが役立つところは、まずファーストクラスモジュールだそうです。

まずは簡単なシグネチャを書いてみます。


module type Id = sig
  type t
  val id : t -> t
end

このシグネチャを持つモジュールを作成する場合、具象のモジュールを作成する方法があります。


module Num = struct
  type t = int
  let id n = n
end

そしてファーストクラスモジュールを使うやり方もあります。


# let num = (module struct type t = int let id n = n end: Id with type t = int) ;;
val num : (module Id with type t = int) = <module>
# module Num = (val num : Id with type t = int) ;;
module Num : sig type t = int val id : t -> t end
# Num.id 1 ;;
- : int = 1 

しかし、上記のようなやり方では何の利便性もなく、柔軟性もありません。なぜなら、例えば同じようにmodule Stringというものを作るとき、let string = ...という新しいファーストクラスモジュールを作らないといけないからです。

そこで登場するのがlocally abstract typeなるものです。

locally abstract type

以下のようなものを作ってみました。


# let make_id (type a) = (module struct type t = a let id n = n end: Id with type t = a) ;;
val make_id : (module Id with type t = 'a) = <module>

こうするとどうなるか?


# module Num = (val make_id: Id with type t = int) ;;
module Num : sig type t = int val id : t -> t end
# Num.id 1 ;;
- : int = 1
# module String = (val make_id: Id with type t = string) ;;
module String : sig type t = string val id : t -> t end
utop # String.id "Hello" ;;
- : string = "Hello

make_idという様々な型を受け取ることができる一つのファーストクラスモジュールだけで、NumもStringも作れるようになりました。

最初のものよりも便利で柔軟になったような気がしないでもない…

もう一つlocally abstract typeが役立つのが、GADTsだそうです。

しかしながら、私の勉強がまだそこまで理解に達していないので、今回は書きません。

まとめand近況

まだまだ使いこなすにはほど遠いlocally abstract typeですが、来年も引き続きOCamlの勉強をしていきたいと思います。

11月、12月と、記事をほとんど書く時間がなかったので、前回の記事からだいぶ時間が空いてしまいました。親父に肺ガンが見つかり、検査等で通院回数が増え、バタバタとしておりました。親父はこれで成人病と言われるものを制覇したのではないだろうか。しかし、本人に治そうという気がないし、全てにおいて他人任せ、他人のせいという考えがあるので、正直自業自得である(糖尿・高血圧にくせに私よりも食っている。そして運動しない) 可哀相なのは母である。母の姉の認知症でショックを受け、自分の認知症への不安も抱えているのに、親父の世話をしなければならない。そんなことを理解しているのかいないのか、親父はずっとテレビを観て、飯とおやつのことばかり考えている。母をできるだけサポートもしくは代役としての生活はこれからもしばらく続くと思われます。がしかし、来年もできるだけ記事を書いていこうと思います。OCaml5.0の動向もチェックしていこうと思います。

それでは皆様、来年皆様にとって良い一年になりますように、心より願っております。