The signature of the >>
function in Haskell is this:
(>>) :: m a -> m b -> m b
And the default implementation is:
x >> y = x >>= \_ -> y
By that, I understand that the >>
function always returns its right parameter regardless of the value of the left one. The lambda is not even caring what the value of the left parameter (x) is. Then, why is Nothing >> Just 3
equal to Nothing
? Shouldn't it just return Just 3
, since that is the value of the argument on the right?
I know that any Just
value, will return Nothing
, when associated with a Nothing
, but in this case the Nothing
is not even being captured by the lambda. What am I missing?
Bonus question, >>=
is called bind. What is >>
called?
Thanks.
The type has two constructors, Just a and Nothing . When a type has multiple constructors, it means that a value of the type must have been constructed with just one of the possible constructors. For this type, a value was either constructed via Just or Nothing , there are no other (non-error) possibilities.
No. However, you can have functions that return a trivial value.
The ++ operator is the list concatenation operator which takes two lists as operands and "combines" them into a single list.
() is very often used as the result of something that has no interesting result. For example, an IO action that is supposed to perform some I/O and terminate without producing a result will typically have type IO () .
Because the bind is not even caring what the value of the lambda is!
Just x >>= f = f x
Nothing >>= _ = Nothing
Note the (Nothing >>=)
does not evaluate its second argument.
To really understand what (>>)
does in this case you have to look at the definition of (>>=)
for Maybe
:
(Just x) >>= k = k x
Nothing >>= _ = Nothing
Nothing >>= k
evaluates to Nothing
regardless of what the k
function is. In the specific case of (>>)
, k
just happens to be \_ -> y
.
By that, I understand that the >> function always returns its right parameter regardless of the value of the left one
This is the source of your confusion!
m >>= f
invokes f
for values it "finds inside" m
, "combining" the results (where what it means for values to be "found inside" a monadic value and what it means to "combine" are monad-specific).
m >> n
has to be equivalent to m >>= \_ -> n
. So for each value it finds inside m
, it will invoke \_ -> n
on it. But Nothing
in the Maybe
monad doesn't have any values "inside" it. So \_ -> n
can't ever even be invoked on anything in order to ignore it and return n
! So Nothing >>= \_ -> n
has to return something that doesn't depend on n
, since it has no way of calling the function to obtain n
. There also aren't any values of the wrapped type floating around in this context, so the only option available is simply Nothing
.
So rather than your intuition for understanding >>
being that it ignores the left and returns what's on the right, it's better to think that it takes the "monadic structure" of what's on the left and binds that with the monadic value on the right. "Monadic structure" is a hand-wavey term for "everything that defines a monadic value other than the values inside it".
listA >> listB
does the same thing regardless of the particular values in listA
, but it matters how many elements are in it. ioA >> ioB
does the same thing regardless of what value is produced by executing ioA
, but it matters side effects were done to produce it. stateA >> stateB
ignores the value produced by stateA
, but sends the current state to stateB
. And maybeA >> maybeB
does the same thing regardless of the particular value inside maybeA
, but it matters whether there is a value or not. Note that the list case behaves very similarly to Maybe
; if listA
is empty then listA >> listB
has to be empty too.
As for your bonus question, when I'm reading code to myself (in my head) I tend to pronounce both >>=
and >>
as "bind"; when I'm looking at the code as well as pronouncing it there's enough non-verbal awareness of the context that this ambiguity doesn't matter. I actually don't know what I would say to talk aloud with someone about >>=
and >>
; maybe "bind" and "forgetful bind"?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With