Confused about `ap`
See original GitHub issueThis article seems to indicate that the function in Container supplying ap
applies its function to the value contained in the functor pass into ap
as a parameter
https://drboolean.gitbooks.io/mostly-adequate-guide-old/content/ch10.html#ships-in-bottles
This article confirms the same idea
https://github.com/hemanth/functional-programming-jargon#applicative-functor
Yet this article seems to imply the reverse, basically ap
is map
https://github.com/fantasyland/fantasy-land#apply
A value which has an Apply must provide an ap
method. The ap
method takes one argument:
a.ap(b)
b
must be an Apply of a function
- If
b
does not represent a function, the behaviour ofap
is unspecified.b
must be same Apply asa
.
a
must be an Apply of any value
ap
must apply the function in Applyb
to the value in Applya
- No parts of return value of that function should be checked.
The
Apply
returned byap
must be the same asa
andb
3 states that b
is a function applied to a.
Suppose we have some Box defined as
const Box = x => ({
map: f => Box(f(x)),
ap: f => f.map(x),
inspect: () => `Box(${x})`,
})
const a = x => x + 1
const b = 4
console.log(
Box( a ).ap( Box( b ) ).inspect() === Box( b ).map( a ).inspect()
)
// true
Is this Box implementing ap
correctly (per these specs)?
Issue Analytics
- State:
- Created 6 years ago
- Reactions:1
- Comments:5 (2 by maintainers)
Top GitHub Comments
I’d like to extend on @paldepind his answer, and go a little more in depth, hopefully alleviating some ambiguity.
The argument order for
ap
changed between Fantasy Land 0.x and 1.0. At the same time, the Fantasy Land spec also changed from specifying a “public” API, to specifying a “private” API. Namely, all methods were prefixed withfantasy-land/
. The Fantasy Land methods are no longer to be used directly.Providing a user-facing, public, method-based API is completely up to the author of a data type. Implementing the
fantasy-land/
-prefixed methods is just to provide a communication layer for interoperability.Some libraries do not expose a public method API at all. For example, Sanctuary and its algebraic types.
Some libraries expose a public method API where the argument order benefits “fluent method chaining” style. For example,
Fluture#ap
has the function on the left-hand side (the instance), similarly to how your Box has it. Fluture also implementsfantasy-land/ap
, with flipped argument order, for interoperability.In the Mostly Adequate Guide, only a public API is implemented, none of which is compatible with Fantasy Land (the confusing bit is that it used to be). Now, Fantasy Land compliance is merely an interoperability layer that can added to constructors, to indicate to other code that their values have algebraic properties.
Just to stress my point. With the new API you do:
Which as a user, you don’t. The new “API” is not for public use.
fantasy-land/
prefix, and the argument order is the wrong way around.@paldepind you say that the argument order for
ap
was changed and is nowb.ap(a)
but it’s still the same in theApply section
.Update?