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
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
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.
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
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.
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
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.