<NME> Reader.ipynb
<BEF> {
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The Reader Monad"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from oslash import Reader\n",
    "unit = Reader.unit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Reader monad pass the state you want to share between functions. Functions may read that state, but can't change it. The reader monad lets us access shared immutable state within a monadic context. In the Reader monad this shared state is called the environment.\n",
    "\n",
    "The Reader is just a fancy name for a wrapped function, so this monad could also be called the Function monad, or perhaps the Callable monad. Reader is all about composing wrapped functions."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A Reader wraps a function, so it takes a callable:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "a = Reader(lambda name: \"Hi %s!\" % name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In Python you can call it as any other callable:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hi Dag!'"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a(\"Dag\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Unit\n",
    "\n",
    "Unit is a constructor that takes a value and returns a Reader that ignores the environment. That is it ignores any value that is passed to the Reader when it's called:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "42"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = unit(42)\n",
    "x(\"Ignored\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Bind\n",
    "\n",
    "You can bind a Reader to a monadic function using the pipe `|` operator (The bind operator is called `>>=` in Haskell). A monadic function is a function that takes a value and returns a monad, and in this case it returns a new Reader monad:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'Hello Dag!'"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r = Reader(lambda name: \"Hi %s!\" % name)\n",
    "\n",
    "b = r | (lambda x: unit(x.replace(\"Hi\", \"Hello\")))\n",
    "b(\"Dag\")"
   ]
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Applicative"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "c =  Reader(lambda x: unit(x + \"!\")) * a"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false
   },
    "collapsed": false
   },
   "outputs": [
    {
       "'Dag!'"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "c(\"Dag\")"
   ]
  },
  {
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# MonadReader\n",
    "\n",
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {
    "collapsed": true
   },
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from oslash import MonadReader\n",
    "asks = MonadReader.asks\n",
    "ask = MonadReader.ask"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ask\n",
    "\n",
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {
    "collapsed": false
   },
    "collapsed": false
    {
     "data": {
      "text/plain": [
       "'VibekeDag'"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r = ask() | (lambda x: unit(\"Vibeke\" + str(x)))\n",
    "r(\"Dag\")"
   ]
  },
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Asks\n",
    "\n",
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {
    "collapsed": false
   },
    "collapsed": false
   },
   "outputs": [
    {
       "6"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
     "output_type": "execute_result"
    }
   ],
   "source": [
    "r = asks(len)\n",
    "r(\"banana\")"
   ]
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## A Longer Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {
    "collapsed": false
   },
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
    }
   ],
   "source": [
    "# Translated to Python from https://gist.github.com/egonSchiele/5752172\n",
    "from oslash import Reader, MonadReader\n",
    "ask = MonadReader.ask\n",
    " \n",
    "ask = MonadReader.ask\n",
    " \n",
    "def hello():\n",
    "    return ask() | (lambda name: \n",
    "           unit(\"Hello, \" + name + \"!\"))\n",
    " \n",
    "def bye():\n",
    "    return ask() | (lambda name: \n",
    "           unit(\"Bye, \" + name + \"!\"))\n",
    " \n",
    "def convo():\n",
    "    return hello() | (lambda c1: \n",
    "           bye() | (lambda c2: \n",
    "           unit(\"%s %s\" % (c1, c2))))\n",
    "\n",
    "r = convo()\n",
    "print(r(\"dag\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "_That is it, that's the Reader monad for you in Python and Ø!_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.4.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}

<MSG> Updated Reader notebook

<DFF> @@ -4,12 +4,22 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "# The Reader Monad"
+    "# The Reader Monad\n",
+    "\n",
+    "The Reader monad pass the state you want to share between functions. Functions may read that state, but can't change it. The reader monad lets us access shared immutable state within a monadic context. In the Reader monad this shared state is called the environment.\n",
+    "\n",
+    "The Reader is just a fancy name for a wrapped function, so this monad could also be called the Function monad, or perhaps the Callable monad. Reader is all about composing wrapped functions.\n",
+    "\n",
+    "This [IPython](http://ipython.org) notebook uses the [OSlash](https://github.com/dbrattli/OSlash) library for Python 3.4, aka Ø. You can install Ø using:\n",
+    "\n",
+    "```bash\n",
+    "> pip3 install oslash\n",
+    "```"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 106,
    "metadata": {
     "collapsed": true
    },
@@ -19,15 +29,6 @@
     "unit = Reader.unit"
    ]
   },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "The Reader monad pass the state you want to share between functions. Functions may read that state, but can't change it. The reader monad lets us access shared immutable state within a monadic context. In the Reader monad this shared state is called the environment.\n",
-    "\n",
-    "The Reader is just a fancy name for a wrapped function, so this monad could also be called the Function monad, or perhaps the Callable monad. Reader is all about composing wrapped functions."
-   ]
-  },
   {
    "cell_type": "markdown",
    "metadata": {},
@@ -37,25 +38,25 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 58,
+   "execution_count": 107,
    "metadata": {
     "collapsed": false
    },
    "outputs": [],
    "source": [
-    "a = Reader(lambda name: \"Hi %s!\" % name)"
+    "r = Reader(lambda name: \"Hi %s!\" % name)"
    ]
   },
   {
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "In Python you can call it as any other callable:"
+    "In Python you can call this wrapped function as any other callable:"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 59,
+   "execution_count": 108,
    "metadata": {
     "collapsed": false
    },
@@ -66,13 +67,13 @@
        "'Hi Dag!'"
       ]
      },
-     "execution_count": 59,
+     "execution_count": 108,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "a(\"Dag\")"
+    "r(\"Dag\")"
    ]
   },
   {
@@ -86,7 +87,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 40,
+   "execution_count": 109,
    "metadata": {
     "collapsed": false
    },
@@ -97,14 +98,14 @@
        "42"
       ]
      },
-     "execution_count": 40,
+     "execution_count": 109,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "x = unit(42)\n",
-    "x(\"Ignored\")"
+    "r = unit(42)\n",
+    "r(\"Ignored\")"
    ]
   },
   {
@@ -118,7 +119,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 61,
+   "execution_count": 110,
    "metadata": {
     "collapsed": false
    },
@@ -126,10 +127,10 @@
     {
      "data": {
       "text/plain": [
-       "'Hello Dag!'"
+       "'Dag!'"
       ]
      },
-     "execution_count": 61,
+     "execution_count": 110,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -143,23 +144,14 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "## Applicative"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 31,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
-   "source": [
-    "c =  Reader(lambda x: unit(x + \"!\")) * a"
+    "## Applicative\n",
+    "\n",
+    "Apply (`*`) is a beefed up `map`. It takes a Reader that has a function in it and another Reader, and extracts that function from the first Reader and then maps it over the second one (basically composes the two functions)."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 111,
    "metadata": {
     "collapsed": false
    },
@@ -170,13 +162,16 @@
        "'Dag!'"
       ]
      },
-     "execution_count": 32,
+     "execution_count": 111,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "c(\"Dag\")"
+    "r = Reader(lambda name: \"Hi %s!\" % name)\n",
+    "\n",
+    "a =  Reader(lambda x: unit(x + \"!\")) * r\n",
+    "a(\"Dag\")"
    ]
   },
   {
@@ -190,7 +185,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 62,
+   "execution_count": 112,
    "metadata": {
     "collapsed": true
    },
@@ -212,7 +207,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 71,
+   "execution_count": 113,
    "metadata": {
     "collapsed": false
    },
@@ -220,16 +215,16 @@
     {
      "data": {
       "text/plain": [
-       "'VibekeDag'"
+       "'Hi Dag!'"
       ]
      },
-     "execution_count": 71,
+     "execution_count": 113,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "r = ask() | (lambda x: unit(\"Vibeke\" + str(x)))\n",
+    "r = ask() | (lambda x: unit(\"Hi %s!\" % x))\n",
     "r(\"Dag\")"
    ]
   },
@@ -244,7 +239,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 57,
+   "execution_count": 114,
    "metadata": {
     "collapsed": false
    },
@@ -255,7 +250,7 @@
        "6"
       ]
      },
-     "execution_count": 57,
+     "execution_count": 114,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -269,12 +264,14 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "## A Longer Example"
+    "## A Longer Example\n",
+    "\n",
+    "This example has been translated to Python from https://gist.github.com/egonSchiele/5752172."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 98,
+   "execution_count": 115,
    "metadata": {
     "collapsed": false
    },
@@ -288,7 +285,6 @@
     }
    ],
    "source": [
-    "# Translated to Python from https://gist.github.com/egonSchiele/5752172\n",
     "from oslash import Reader, MonadReader\n",
     "ask = MonadReader.ask\n",
     " \n",

Updated Reader notebook