3 ms·
A functor is two things: - a parametrized type, like for instance List: you can have lists of integers, floats, functions, or any other type - a way of mappin
by chombier 5y ago
A functor is two things:
- a parametrized type, like for instance List: you can have lists of integers, floats, functions, or any other type
- a way of mapping (in the sense of List.map) between instances of the parametrized type, given regular functions. This mapping should behave nicely with respect to regular function composition.
If your parametrized type is F, then the mapping operation turns ("lifts") regular functions A -> B into functions (F A) -> (F B) in a reasonable way: "if you give me a function then I can transform any list using it".
Functors can be used to "decorate" values: you can model exceptions (some value or an error), promises (some value not yet computed), state (some value + side effects) and many other kinds of effects using functors.
So in general an effectful computation will have type A -> (F B) for some functor F modeling the effect. And now you have a problem: how to compose effectful computations in order to build larger programs out of smaller ones? You cannot simply compose A -> (F B) with B -> (F C) since the types don't match.
What you need is a way of transforming an effectful computation B -> (F C) into a lifted function (F B) -> (F C) so that you can compose A -> (F B) with (F B) -> (F C) in order to get A -> (F C).
That device should satisfy some properties to make effectful composition work the way you expect (in particular there should exist identity effectful computations), and is called a monad.
A monad is a functor + some extra operations (bind/return) satisfying properties that will make effectful computations (using this functor) composable.
The type of bind is generally written (F A) -> (A -> F B) -> (F B) but really it is the same as (A -> F B) -> (F A -> F B) above (takes an effectful computation, gives back a lifted function).
- bruce343434 5y agoClearer and more succinct than TFA, thank you
- rocqua 5y ago> What you need is a way of transforming an effectful computation B -> (F C) into a lifted function (F B) -> (F C) so that you can compose A -> (F B) with (F B) -> (F C) in order to get A -> (F C). isn't this just applicative? What is needed to turn applicative into monad?
- datatrashfire 5y agoThis was better than the tutorial, thank you.
- nicolasrusso 5y agoI'm sorry I still barely understand what's going on here. Too many unfamiliar terms. Should note I don't have a CS nor math background, just basic programming. Here's my best understanding so far: A functor is a function that takes in a list of things and like a regular function, outputs a list of modified things... So how is this different from a function?
- chobytes 5y agoA functor is a certain kind of function (Theres a pedantic point to be made but it's mostly irrelevant). However, most functions are not functors. To give a simpler example, we say a function, f, is monotone when for x<y, f(x)<f(y); that is, it preserves order. Every monotone function is obviously a function, but functions like x^2 are not monotone. Basically a functor is a function which preserves some other properties. I wont go into detail as many have before me, but thats the gist.
- nicolasrusso 5y agoInteresting, thank you! For those who like me wanted to see the edge case for the non-monotonic function, if you do: -2 < -1 -2 is in fact less than -1. However: (-2)^2 < (-1)^2 ==becomes==> 4 < 1 And 4 is obviously not less than 1.