What does (T: {type t;})?


#1

Hi all
I saw the following code:

module Impl = (T: {type t;}) => {

in https://github.com/reasonml-community/bs-webapi-incubator/blob/master/src/dom/nodes/ElementRe.re and wanted to know what does (T: {type t;}) mean.

Thanks


#2

It is directly analogous to how values work @bifunctor
For example here is a function which takes in the value t which is constrained to be a list('a):
let a = (t: list('a)) => {

Similarly, module Impl = (T: {type t;}) => { is a functor (sort of like a function which operates on types) which takes in a module value of T which is constrained to have the shape of {type t;} (the module T has to have a type named t within it). (T: {type t;}) => {} returns another module. Since you’re constraining module T to have a particular shape, you can only access type t from this module value and not any other functions or types within it.


#3

First of all, thanks for your answer.
I know functor in Haskell, for example f a. f is a functor and a is value, that the functor wraps.
What does {type t;} mean? I can not see any abstraction. There is no value to put inside.
Thanks


#4

It is abstract in the sense that type t could be a string or a int, a list or any other concrete type available in the ocaml type system. For example Impl({ type t = string; }) returns a module which can perform operations on the concrete module provided to it. This is useful for things like data structures where you need functions which can do things like hash a value or compare two elements of an unknown type. The implementation of the data structure doesn’t need to know about such details and can simply take in a module which provides both type t and the operations it might need to get the job done.


#5

Looking at the following example:

open Webapi.Dom;

let component = ReasonReact.statelessComponent("NavBulkView");

let setSectionRef = (theRef, _self) => {
  Js.log(Element.innerText(theRef));
};

let make = (_children) => {
  ...component,
  didMount: _self => {

    let ele = Document.querySelector("#foo", document);
    switch ele {
    | None => Js.log("Nothing")
    | Some(a) => Js.log(Element.innerText(a))
    };

    ReasonReact.NoUpdate;
  },
  render: self => {
    <div id="foo" ref={self.handle(setSectionRef)}>
      {ReasonReact.stringToElement("Hello")}
    </div>
  }
};

The compiler complains:

  This has type:
    ReasonReact.Callback.t(Webapi.Dom.Element.t) (defined as
      Webapi.Dom.Element.t => unit)
  But somewhere wanted:
    Js.nullable(Dom.element) => unit

  The incompatible parts:
    Webapi.Dom.Element.t (defined as
      Dom.eventTarget_like(Dom._node(Dom._element(Dom._baseClass))))
    vs
    Js.nullable(Dom.element)

To be honest, I am confused about type. What is the type of theRef?

THanks


#6

I know functor in Haskell

Note: a functor in Reason/OCaml is a different beast than in Haskell

In OCaml, a functor is a function from module to module.