language: Python (python 2.7.3)
date: 395 days 0 hours ago
link:
visibility: public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class ListMonad(list):
    @staticmethod
    def return_(x): return ListMonad([x])
    def bind(self, f): return ListMonad(x for it in self for x in f(it))
 
lst = [1, 2, 3, 4]
 
# this:
print ListMonad(lst).bind(
        lambda x: ListMonad.return_(x * 2).bind(
                lambda y: ListMonad.return_(y) if y % 3 else ListMonad()))
 
# is the same as this:
print filter(lambda y: y % 3, map(lambda x: x * 2, lst))  
                                  
 
# But this can't be done with map:
print ListMonad(lst).bind(
        lambda x: ListMonad(lst).bind(
                lambda y: ListMonad.return_(x * y)))
 
# because if we use map, we get a list of lists:
print map(lambda y: map(lambda x: x * y, lst), lst)
 
 
input = ['first input', 'second input']
class IOMonad():
    def __init__(self, x = None):
        self.x = x
    @staticmethod
    def return_(x): return IOMonad()
    def bind(self, f): return f(self.x)
    @staticmethod
    def readLn():
        return IOMonad(input.pop(0)) # don't want actual interaction here
    @staticmethod
    def putStr(s):
        print s
        return IOMonad()
 
# this performs side effects and returns an instance of IOMonad, as it should
print IOMonad.readLn().bind(
        lambda s1: IOMonad.readLn().bind(
                lambda s2: IOMonad.putStr('you wrote: ' + s1 + ' and then ' + s2)))