1

我来自 Javascript 背景,我试图了解如何使用 Reason/Ocaml 的模块系统构建/构建程序。

作为一个练习,假设我想在 OCaml/Reason 中编写这段 javascript(将通过 js_of_ocaml 将其编译回 js)

var TeaType = new GraphQLObjectType({
     name: 'Tea',
     fields: () => ({
       name: {type: GraphQLString},
       steepingTime: {type: GraphQLInt},
   }),
}); 

我应该如何设计我的程序来实现这一点?

我是否应该制作一个模块,该模块需要另一个模块通过 js_of_ocaml 在 js 中生成 GraphQLObjectType?

我将如何构造这种支持 GraphQLObjectType 的类型?

Tea.re
let name = "Tea";
let fields = /* what type should I make for this? Tea is 
             just one of the many graphql-types I'll probably make */

我的意思是 fields 是一个 thunk,它返回一个包含未知数量的字段的地图。(每个graphqlobject都有不同的字段)这个在OCaml/Reason中映射到什么类型,我需要自己制作吗?

4

1 回答 1

1

只是为了让您感受 OCaml 的味道,直接(句法)翻译将是:

   let tea_type = GraphQL.Object.{
      name = "Tea";
      fields = fun () -> QraphQL.Field.[{
           name = GraphQL.Type.{name : GraphQL.string }
           steeping_time = GraphQL.Type.{name : QraphQL.int }
      }]
   }

基本上,我将 js 对象映射到 OCaml 的记录。OCaml 中也有带有方法和继承的对象,但我认为记录仍然是一个更接近的抽象。这些记录可以看作是一个命名元组,当然,也可以包含函数。模块,是比较重的抽象,也是字段的集合。与记录不同,模块可能包含类型、其他模块以及基本上任何其他语法结构。由于类型在编译时被删除,模块的运行时表示与记录的表示完全一样。模块还定义了命名空间。由于 OCaml 记录是由它们的字段名称定义的,因此在其自己的模块中定义每个记录总是有用的,例如,

module GraphQL = struct
  let int = "int"
  let string = "string"

  module Type = struct
    type t = {
      name : string
    }
  end

  module Field = struct 
    type t = {
      name : string;
      steeping_time : Type.t
    }
  end

  module Object = struct 
    type t = {
      name : string;
      fields : unit -> Field.t list
  end
end
于 2016-06-01T12:48:15.497 回答