Reputation: 2412
I'm coming from a Javascript background & I'm trying to understand how I need to structure/build a program with Reason/Ocaml's module system.
As an exercise let's say I want to write this piece of javascript in OCaml/Reason (will compile it back to js through js_of_ocaml)
var TeaType = new GraphQLObjectType({
name: 'Tea',
fields: () => ({
name: {type: GraphQLString},
steepingTime: {type: GraphQLInt},
}),
});
How should I design my program to accomplish this?
Should I make a module which takes another module to produce a GraphQLObjectType in js through js_of_ocaml?
How would I structure this type that backs a 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 */
I mean fields is a thunk which returns a map that contains an unknown amount of fields. (every graphqlobject has different fields) To what type does this map in OCaml/Reason, do I need to make my own?
Upvotes: 1
Views: 280
Reputation: 35210
Just for you to feel the flavor of OCaml, the direct (syntactic) translation would be:
let tea_type = GraphQL.Object.{
name = "Tea";
fields = fun () -> QraphQL.Field.[{
name = GraphQL.Type.{name : GraphQL.string }
steeping_time = GraphQL.Type.{name : QraphQL.int }
}]
}
Basically, I mapped js objects to OCaml's records. There are also objects in OCaml with methods and inheritance, but I think that records are still a closer abstraction. The records can be seen as a named tuple, and, of course, can contain functions. Modules, are more heavy weight abstractions, that is also a collection of fields. Unlike records, modules may contain types, other modules, and basically any other syntactic construction. Since types are removed at compile time, the runtime representation of a module is absolutely the same as the representation of records. Modules also define namespaces. Since OCaml records are defined by the names of their fields, it is always useful to define each records in its own module, e.g.,
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
Upvotes: 1