The explanation at https://github.com/hemanth/functional-programming-jargon , unfortunately, is not very accurate.
A The indicated functor is indeed a functor F together with the of function defined for each type a and sends the value x type a to the value of(x) type F a . The signature of Hindley-Milner is as follows:
of :: a -> F a
For example, the Array function is specified using of = x => [x] defined for each value x any type a .
In addition, the function of (or, more precisely, the set of functions of , as you have for each type of a ), must be a natural transformation from an identity functor to F This means that of value of the function is equal to of argument displayed by the same function:
of(f(x)) === of(x).map(f)
For example, in the Array example, you have
[f(x)] === [x].map(f),
therefore x => [x] indeed a natural transformation.
But you can also take
of = x => [x, x] [f(x), f(x)] === [x, x].map(f)
which is another pointed functor, even if the map functor remains unchanged. (Note that in each case you only get special arrays as the values of(x) .)
However, you cannot take, for example.
of = x => [x, 0] [f(x), 0] !== [x, 0].map(f)
Now
var grid = Grid.of({ width: 2, height: 2, list: [1, 2, 3, 4] })
works fine and returns your object passed to the Grid . You can then map your Grid to any regular F function from simple objects to simple objects, and the result will be the same as applying F and transferring to the Grid due to the law of natural transformation. Note that this way you can also call Grid.of with any other value, for example Grid.of({width: 2}) even Grid.of(2) . Alternatively, you can restrict the types for which Grid.of is defined, then the value should be only the type that you allow.
This is a little tricky:
Grid.of(2, 2, [1, 2, 3, 4])
This applies to Grid.of for several arguments. Since Grid.of by definition a function of only one argument, the result will be Grid.of(2) , which may not be what you want. If you really want to supply all the values, you probably want to write
Grid.of([2, 2, [1, 2, 3, 4]])
Alternatively, you can extend Grid.of by several arguments, first wrapping them in an array inside, and then applying Grid.of It really depends on what you are after.
For an example of real-world use, see, for example, here , where a "boring" task is defined through Task.of from a simple value. On the other hand, here is a more interesting task wrapping a function that you would not get with Task.of The important thing is that both Tasks can be used with the same uniform interface, as shown in both examples.
Also note that applicative functors are not used in these examples, so pointed functors are still used without use.