我来自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中是什么类型的,我需要制作自己的吗?
答案 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