aboutsummaryrefslogtreecommitdiff
path: root/wqflask/utility/monads.py
diff options
context:
space:
mode:
Diffstat (limited to 'wqflask/utility/monads.py')
-rw-r--r--wqflask/utility/monads.py80
1 files changed, 80 insertions, 0 deletions
diff --git a/wqflask/utility/monads.py b/wqflask/utility/monads.py
new file mode 100644
index 00000000..fbcb2c23
--- /dev/null
+++ b/wqflask/utility/monads.py
@@ -0,0 +1,80 @@
+"""Monadic utilities
+
+This module is a collection of monadic utilities for use in
+GeneNetwork. It includes:
+
+* MonadicDict - monadic version of the built-in dictionary
+* MonadicDictCursor - monadic version of MySQLdb.cursors.DictCursor
+ that returns a MonadicDict instead of the built-in dictionary
+"""
+
+from collections import UserDict
+from functools import partial
+
+from MySQLdb.cursors import DictCursor
+from pymonad.maybe import Just, Nothing
+
+class MonadicDict(UserDict):
+ """
+ Monadic version of the built-in dictionary.
+
+ Keys in this dictionary can be any python object, but values must
+ be monadic values.
+ """
+ def __init__(self, d, convert=True):
+ """
+ Initialize monadic dictionary.
+
+ If convert is False, values in dictionary d must be
+ monadic. If convert is True, values in dictionary d are
+ converted to monadic values.
+ """
+ if convert:
+ super().__init__({key:(Nothing if value is None else Just(value))
+ for key, value in d.items()})
+ else:
+ super().__init__(d)
+ def __getitem__(self, key):
+ """
+ Get key from dictionary.
+
+ If key exists in the dictionary, return a Just value. Else,
+ return Nothing.
+ """
+ try:
+ return Just(self.data[key])
+ except KeyError:
+ return Nothing
+ def __setitem__(self, key, value):
+ """
+ Set key in dictionary.
+
+ value must be a monadic value---either Nothing or a Just
+ value. If value is a Just value, set it in the dictionary. If
+ value is Nothing, do nothing.
+ """
+ value.bind(partial(super().__setitem__, key))
+ def __delitem__(self, key):
+ """
+ Delete key from dictionary.
+
+ If key exists in the dictionary, delete it. Else, do nothing.
+ """
+ try:
+ super().__delitem__(key)
+ except KeyError:
+ pass
+
+class MonadicDictCursor(DictCursor):
+ """
+ Monadic version of MySQLdb.cursors.DictCursor.
+
+ Monadic version of MySQLdb.cursors.DictCursor that returns a
+ MonadicDict instead of the built-in dictionary.
+ """
+ def fetchone(self):
+ return MonadicDict(super().fetchone())
+ def fetchmany(self, size=None):
+ return [MonadicDict(row) for row in super().fetchmany(size=size)]
+ def fetchall(self):
+ return [MonadicDict(row) for row in super().fetchall()]