Correct implementation of fmap for Functors?

Viewed 111

So, I have been trying to wrap my mind around Functors, Applicatives and Monads lately. In my understanding such a design pattern allows one to separate "pure functions" from "impure" ones and ensure that there is no branching out and calling different functions from a given function and cause side effects.

So, let's say I have a dictionary and want to apply/compose some functions over it.

input = {"x": 2, "y": 5, "out": None}

def f(x):
    return x + 2

def g(y):
    return y - 3

def h(x, y):
    return x * y

class Functor:

    def __init__(self, input):
        self.input = input

    def fmap(self, function):
        val = self.input
        if function.__name__ == "f":
            val["x"] = function(val["x"])
        elif function.__name__ == "g":
            val["y"] = function(val["y"])
        elif function.__name__ == "h":
            val["out"] = function(val["x"], val["y"])
        elif function.__name__ == "print":
            function(val)
        else:
            print("fmap not defined for this function!")
        return Functor(val)

    def __rshift__(self, function):
        return self.fmap(function)

Functor(input) >> f >> g >> h >> print #results in {"x": 4, "y": 2, "out": 8}
Functor(input) >> h >> g >> h >> print #results in {"x": 2, "y": 2, "out": 4}
Functor(input) >> g >> f >> h >> print #results in {"x": 4, "y": 2, "out": 8}

So, is my understanding of functors correct? If yes, is this the way one implements the fmap, or do you create a wrapper around each function so as to define the fmap inside the respective wrapper or what? And, is this the way to keep track of the state of inputs, post function application?

0 Answers
Related