I am trying to understand maybe Monad but most of the examples I saw used some language-specific feature. To ensure that I have gotten it conceptually right I thought of writing a generic implementation. Below is what I came up with.
Can someone tell if I have gotten it conceptually right? Is there a better way to generalize it?
def f():
return 2
def g():
return 4
def h():
return 7
def i():
return None
def bind(val, func):
if val is None:
return None
else:
return(func())
unit = 0
>>> bind(bind(bind(unit,f),i),h) #Returns nothing
>>> bind(bind(bind(unit,f),g),h) #Returns a value
>>>7
What if I wanted to add the values from these functions and abort if any of those was NULL; any suggestion?
You're very close, but the signature of bind
is
m a -> (a -> m b) -> m b
So it's "unwrapping" m
and passing the contained value to the next function. You currently have
m a -> ( () -> m b) -> m b
Since you're just ignoring the val
bind gets, you should have
def bind(val, func):
if val is None:
return None
else:
return(func(val))
This is equivalent to >>=
in Haskell. What you had before was >>
which should be implemented as
# "ignore" bind
def ibind(val, func):
bind(val, lambda _ : func())
which just happily throws away the value bind
passes it.
To take this further, you'd have to introduce a class
class Maybe():
def __init__(v):
self.val = v
self.isNothing = False
Nothing = Maybe(None)
Nothing.isNothing = True
def bind(val, func):
if val.isNothing:
return Nothing
else:
return(func(val.val))
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