Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

simplifying maybe Monad

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?

like image 412
Dev Maha Avatar asked Jul 25 '13 18:07

Dev Maha


1 Answers

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))
like image 53
Daniel Gratzer Avatar answered Oct 01 '22 21:10

Daniel Gratzer