OCaml / reason设计模块

时间:2016-05-31 20:06:20

标签: ocaml reason

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

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

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

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

我是否应该创建一个模块,该模块需要另一个模块在js到js_of_ocaml中生成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 */

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

1 个答案:

答案 0 :(得分:0)

为了让您感受到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