I replied to this a bit on the Discord chat, but I’ll repost some of that here for posterity.
I’m skeptical that this is a good example for using a functor or a first-class-module. Since all it does is return new functions based on the functions given to it, you could achieve the same thing much easier with a plain-old higher-order-function.
// Return a record with the functions we need:
let make = (~fromUrl, ~toString) => {
useRouter: ...,
push: ...,
replace: ...,
}
Or you could put it all in a React hook to make the API even simpler:
let useRouter = (~fromUrl, ~toString) => {
route: fromUrl(ReasonReactRouter.useUrl()),
push: route => route->toString->ReasonReactRouter.push,
replace: route => route->toString->ReasonReactRouter.replace,
}
// in your component:
let {route, push, replace} = useRouter(~fromUrl, ~toString)
If you want to use a functor, I’m not sure if the created module would be needed to be passed down your component tree as props. Its only dependencies are the fromUrl
and toString
functions, which I assume are static across each project.
Here’s a way to use a functor but with a bit easier of an API:
// CommonRouter.res
module Make = (Router: RouterType) => {
type t = ...
let fromUrl = ...
let toString = ...
let useRouter = ...
let push = ...
let replace = ...
}
// ProjectARouter.res
include CommonRouter.Make({
type t = ...
let fromUrl = ...
let toString = ...
})
// ProjectAComponent.res
@react.component
let make = (~to_, ~push=?) => {
let push = push |> Relude.Option.getOrElse(false);
React.useEffect1(
() =>
if (push) {
ProjectARouter.push(to_);
} else {
ProjectARouter.replace(to_);
},
(to_, push),
);
};
You can still reuse logic across projects but without all of the hassle.
I know this doesn’t actually answer your question about using a module as an argument, but I think there’s probably a better solution to this particular problem.
That being said, I also don’t want to discourage exploring functors and first-class-modules, because you can use them to do some genuinely cool stuff. Just be aware they aren’t always worth the hassle if there’s a simpler solution.