File: hexpr_polymorphic.ml

package info (click to toggle)
ocaml-visitors 20200210-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,896 kB
  • sloc: ml: 4,077; makefile: 44; sh: 18
file content (52 lines) | stat: -rw-r--r-- 1,653 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
open Hashcons

module VisitorsHashcons = struct

  (* We CAN implement the method [visit_hash_consed], but this method requires
     a hash-consing table. We assume that this table is stored in the field
     [_table], which we declare virtual. *)

  (* A key subtlety is that the method [visit_hash_consed] must be monomorphic
     in ['b]. Indeed, we cannot hope to build values of type ['b hash_consed]
     for every ['b]. We can only hope to build values of type ['b hash_consed]
     for a fixed ['b], where the hash-consing table has type ['b Hashcons.t].
     For now, the type ['b] is undetermined. It will be fixed in a subclass,
     where the field [_table] is initialized. *)

  class virtual ['self] map = object (_ : 'self)
    val virtual _table: 'b Hashcons.t
    method visit_hash_consed: 'env 'a .
      ('env -> 'a -> 'b) ->
      'env -> 'a hash_consed -> 'b hash_consed
    = fun visit_'a env { node = e; _ } ->
        hashcons _table (visit_'a env e)
  end

end

(* This allows us to define the types [expr] and [hexpr] and generate a
   visitor class for them. *)

type 'expr oexpr =
  | EConst of int
  | EAdd of 'expr * 'expr

and hexpr =
  H of hexpr oexpr hash_consed [@@unboxed]

[@@deriving visitors { variety = "map"; polymorphic = ["'expr"];
                       ancestors = ["VisitorsHashcons.map"] }]

(* Once the type [hexpr] is defined, we can allocate a table. *)

let table : hexpr oexpr Hashcons.t =
  Hashcons.create 128

(* Inheriting [map] and defining [_table] yields a working visitor. *)

let id : hexpr -> hexpr =
  let o = object
    inherit [_] map
    val _table = table
  end in
  o # visit_hexpr ()