Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! /usr/bin/env python3
- """An optional type monad."""
- class Option:
- """Optional type."""
- def __init__(self, contains, *value):
- if contains:
- self.value = value[0]
- self.contains = True
- else:
- self.value = None
- self.contains = False
- def __repr__(self):
- return str((self.contains, self.value))
- def __eq__(self, arg):
- return self.value == arg.value
- def bind(value: Option, function):
- """A function more or less equivalent to the 'bind' operator in
- Haskell that is used for building function chains for processing
- optional monadic values"""
- if value.contains:
- return function(value.value)
- return value
- def increment(value):
- """Incretment a value and wrap it in the optional value."""
- return Option(True, value + 1)
- def fuck_up_chain(value):
- """Emulate failure."""
- return Option(False, None)
- OUTPUT_TEXT = [
- "1. An empty optional value:",
- Option(False),
- "2. A non-empty optional value:",
- Option(True, 7),
- "3. Applying the 'bind' to the empty optional value and the increment function:",
- "bind(Option(False), increment) →",
- bind(Option(False), increment),
- "4. Applying the 'bind' to the non-empty optional value and the increment function:",
- "bind(Option(True, 7), increment) →",
- bind(Option(True, 7), increment),
- "5. Nested (chained) 'bind' application:",
- "bind(bind(Option(True, 7), increment), increment) →",
- bind(bind(Option(True, 7), increment), increment),
- "6. Introducing failure to the chain:",
- "bind(bind(bind(Option(True, 7), increment), fuck_up_chain), increment) →",
- bind(bind(bind(Option(True, 7), increment), fuck_up_chain), increment),
- "7. The first monadic law: return a >>= h ≡ h a",
- "bind(Option(True, 7), increment) == increment(7) →",
- bind(Option(True, 7), increment) == increment(7),
- "8. The second monadic law: m >>= return ≡ m",
- "bind(Option(True, 7), (lambda x: Option(True, x))) == Option(True, 7) →",
- bind(Option(True, 7), (lambda x: Option(True, x))) == Option(True, 7),
- "9. The third monadic law: \
- (m >>= g) >>= h ≡ m >>= (\\x -> g x >>= h)",
- "bind(bind(Option(True, 7), increment), increment) == \
- bind(Option(True, 7), (lambda x: bind(increment(x), increment))) →",
- bind(bind(Option(True, 7), increment), increment) == \
- bind(Option(True, 7), (lambda x: bind(increment(x), increment)))
- ]
- for line in OUTPUT_TEXT:
- print(line)
- # 1. An empty optional value:
- # (False, None)
- # 2. A non-empty optional value:
- # (True, 7)
- # 3. Applying the 'bind' to the empty optional value and the increment function:
- # bind(Option(False), increment) →
- # (False, None)
- # 4. Applying the 'bind' to the non-empty optional value and the increment function:
- # bind(Option(True, 7), increment) →
- # (True, 8)
- # 5. Nested (chained) 'bind' application:
- # bind(bind(Option(True, 7), increment), increment) →
- # (True, 9)
- # 6. Introducing failure to the chain:
- # bind(bind(bind(Option(True, 7), increment), fuck_up_chain), increment) →
- # (False, None)
- # 7. The first monadic law: return a >>= h ≡ h a
- # bind(Option(True, 7), increment) == increment(7) →
- # True
- # 8. The second monadic law: m >>= return ≡ m
- # bind(Option(True, 7), (lambda x: Option(True, x))) == Option(True, 7) →
- # True
- # 9. The third monadic law: (m >>= g) >>= h ≡ m >>= (\x -> g x >>= h)
- # bind(bind(Option(True, 7), increment), increment) == bind(Option(True, 7), (lambda x: bind(increment(x), increment))) →
- # True
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement