How to interpret bind/>>= of the function instance?
applicative, functional-programming, haskell, monads
Solution
The values in the monad instance for functions have type `r -> a` for some fixed type `r`. The function `(a -> (r -> b))` given to `(>>=)` allows you to choose the next function to return given the result from the current value (a function `r -> a`). `f r` has type `a` and `k (f r)` has type `r -> b` which is the next function to apply.
In your code `g(f(x))` is therefore a function which expects a single argument of type `r`. The caller of `bind` can choose this function based on the value returned by the previous function e.g.
var inc = x => x + 1;
var f = bind(inc)(function(i) {
if(i <= 5) { return x => x * 2; }
else { return x => x * 3; }
});
The function will be given `x` as an input and can choose the next stage in the computation based on the result of `inc(x)` e.g.
f(2) //4;
f(5) //15;
Problem
I'm trying to improve my understanding of `Applicative`s and `Monad`s by implementing their function instances in Javascript. My knowledge of Haskell is limited and I hope that my question makes sense at all. Here are my implementations of `fmap`, `<*>` and `>>=` for the `Functor`, `Applicative` and `Monad` typeclasses in Javascript: ``` const fmap = f => g => x => f(g(x)); // B combinator const apply = f => g => x => f(x) (g(x)); // S combinator const bind = f => g => x => g(f(x)) (x); // ? ``` I am not sure whether `bind` is the correct translation of the Haskell implementation: ``` (>>=) :: (r -> a) -> (a -> (r -> b)) -> r -> b instance Monad ((->) r) where f >>= k = \ r -> k (f r) r ``` Provided that `bind` is correct, how is it interpreted? I know that an `Applicative` can sequence effectful computations. I also know that a `Monad` in addition allows you to determine a next effect according to the result of a previous one. I can see the sequences (eager evaluation order in Javascript): - `apply`: `f(x)` ... `g(x)` ... `lambda(result of g)` ... result of `lambda` - `bind`: `f(x)` ... `g(result of f)` ... `lambda(x)` ... result of `lambda` However, the `bind` function looks pretty weird. Why are `f` and `g` nested the other way around? How is the specific `Monad` behavior (determines a next effect according to a previous one) reflected in this implementation? Actually `g(f(x)) (x)` looks like a function composition with flipped arguments, where `g` is a binary function. When I apply `apply`/`bind` with an unary and a binary function, they yield the same result. This doesn't make much sense.