2013-12-30 17:18:10 -05:00
{
"metadata": {
"language": "haskell",
"name": ""
},
"nbformat": 3,
"nbformat_minor": 0,
"worksheets": [
{
"cells": [
2014-01-09 12:48:04 -05:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
2014-01-09 13:04:34 -05:00
"\n",
"\n",
2014-01-09 12:48:04 -05:00
"IHaskell Notebook\n",
2014-01-09 13:04:34 -05:00
"===\n",
"Hello, and welcome to the **IHaskell Notebook**. IHaskell Notebook is similar to an interactive shell along the lines of GHCi. However, it is much more powerful, and provides features such as syntax highlighting, autocompletion, multi-line input cells, integrated documentation, rich output visualization, and more. In this notebook, I'd like to demonstrate many of the awesome features IHaskell provides.\n",
2014-01-09 12:48:04 -05:00
"\n",
2014-01-09 13:04:34 -05:00
"IHaskell is implemented as a language kernel for the [IPython](http://ipython.org) project, which means that although the entire thing is written only in Haskell, we get a beautiful notebook interface practically for free.\n",
2014-01-09 12:48:04 -05:00
"\n",
2014-01-09 13:04:34 -05:00
"We can start with very simple Haskell expressions:"
2014-01-09 12:48:04 -05:00
]
},
2013-12-30 17:18:10 -05:00
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- First of all, we can evaluate simple expressions.\n",
"3 + 5\n",
"\"Hello, \" ++ \"World!\""
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"text": [
"8"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"\"Hello, World!\""
]
}
],
2014-01-09 13:04:34 -05:00
"prompt_number": 1
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As you can see, each input cell get an execution number. The first input cell is labeled `In [1]`. Just like in GHCi, the output of the last executed statement or expression is available via the `it` variable - however, in addition, the output of the $n$th cell is available via the `itN` variable. For example, if we wanted to see what the first cell printed, we can go ahead and output that:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"it1"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"text": [
"\"Hello, World!\""
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 5
2013-12-30 17:18:10 -05:00
},
2014-01-09 13:04:34 -05:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In addition to simple code cells such as the ones you see, you can also have other types of cells. All of this inline text, for instance, is written using Markdown cells, which support the majority of Github markdown syntax. This lets you embed images and formatting and arbitrary HTML interspersed with your Haskell code. In addition, you can export these notebooks into HTML or even as presentations using `reveal.js`. \n",
"\n",
"Alright, back to code. Let's do something slightly fancier:"
]
},
2013-12-30 17:18:10 -05:00
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- Unlike in GHCi, we can have multi-line expressions.\n",
"concat [\n",
2014-01-09 14:58:34 -05:00
" \"Hello\",\n",
2013-12-30 17:18:10 -05:00
" \", \",\n",
" \"World!\"\n",
2014-01-09 13:04:34 -05:00
" ] :: String"
2013-12-30 17:18:10 -05:00
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"text": [
2014-01-09 14:58:34 -05:00
"\"Hello, World!\""
2013-12-30 17:18:10 -05:00
]
2014-01-09 13:04:34 -05:00
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 6
2014-01-09 13:04:34 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In addition to multi-line expressions, IHaskell supports most things that you could put in a standard Haskell file. For example, we can have function bindings without the `let` that GHCi requires. (As long as you group type signatures and their corresponding declarations together, you can use pattern matching and put signatures on your top-level declarations!)"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"thing :: String -> Int -> Int\n",
"thing \"no\" _ = 100\n",
"thing str int = int + length str\n",
"\n",
"thing \"no\" 10\n",
"thing \"ah\" 10"
],
"language": "python",
"metadata": {},
"outputs": [
2013-12-30 17:18:10 -05:00
{
"metadata": {},
"output_type": "display_data",
"text": [
"100"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"12"
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 7
2014-01-09 13:04:34 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So far we've just looked at pure functions, but nothing is stopping us from doing IO."
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"print \"What's going on?\""
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"text": [
"\"What's going on?\""
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 8
2014-01-09 13:04:34 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"IHaskell supports most GHC extensions via the `:extension` directive (or any shorthand thereof)."
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- We can disable extensions.\n",
":ext NoEmptyDataDecls\n",
"data Thing"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
2014-01-09 12:39:50 -05:00
"<span class='err-msg'>`Thing' has no constructors (-XEmptyDataDecls permits this)<br/>In the data declaration for `Thing'</span>"
2013-12-30 17:18:10 -05:00
],
"metadata": {},
"output_type": "display_data",
"text": [
2014-01-09 12:39:50 -05:00
"`Thing' has no constructors (-XEmptyDataDecls permits this)\n",
"In the data declaration for `Thing'"
2013-12-30 17:18:10 -05:00
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 9
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- And enable extensions.\n",
":ext EmptyDataDecls\n",
"data Thing"
],
"language": "python",
"metadata": {},
"outputs": [],
2014-01-09 14:58:34 -05:00
"prompt_number": 10
2014-01-09 13:04:34 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Data declarations do pretty much what you expect, and work fine on multiple lines. If a declaration turns out to be not quite what you wanted, you can just go back, edit it, and re-evaluate the code cell."
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- Various data declarations work fine.\n",
"data One\n",
" = A String\n",
" | B Int\n",
" deriving Show\n",
"\n",
"print [A \"Hello\", B 10]"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"text": [
"[A \"Hello\",B 10]"
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 11
2014-01-09 13:04:34 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Although this doesn't hold everywhere, we've tried to keep IHaskell relatively similar to GHCi in terms of naming. So, just like in GHCi, you can inspect types with `:type` (or shorthands):"
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- We can look at types like in GHCi.\n",
":ty 3 + 3"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
2014-01-09 12:39:50 -05:00
"<span class='get-type'>forall a. Num a => a</span>"
2013-12-30 17:18:10 -05:00
],
"metadata": {},
"output_type": "display_data",
"text": [
"forall a. Num a => a"
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 12
2014-01-09 13:04:34 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The same goes for the `:info` command. However, unlike GHCi, which simply prints info, the IHaskell notebook brings up a separate pane."
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
2014-01-09 13:04:34 -05:00
"-- What is the Integral typeclass?\n",
2013-12-30 17:18:10 -05:00
":info Integral"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
2014-01-09 12:39:50 -05:00
"output_type": "display_data"
2013-12-30 17:18:10 -05:00
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 13
2014-01-09 13:04:34 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you're looking at this notebook after it's been exported to HTML, you won't be able to see this interactive pane. However, it looks approximately like this:\n",
"\n",
2014-01-09 13:34:00 -05:00
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can now write slightly more complicated scripts."
2014-01-09 13:04:34 -05:00
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- Results are printed as we go, even from a single expression.\n",
"import Control.Monad\n",
"import Control.Concurrent\n",
"\n",
"forM_ [1..5] $ \\x -> do\n",
" print x\n",
2014-01-09 13:34:00 -05:00
" threadDelay $ 200 * 1000"
2013-12-30 17:18:10 -05:00
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"text": [
"1\n",
"2\n",
"3\n",
"4\n",
"5"
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 14
2014-01-09 13:34:00 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is where the similarities with GHCi end, and the particularly shiny features of IHaskell begin.\n",
"\n",
"Although looking at text outputs is often enough, there are many times where we really want a richer output. Suppose we have a custom data type for color:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"data Color = Red | Green | Blue"
],
"language": "python",
"metadata": {},
"outputs": [],
2014-01-09 14:58:34 -05:00
"prompt_number": 15
2014-01-09 13:34:00 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If we were playing around with designing GUI applications for color-blind users, we might want to actually *see* these colors, instead of just seeing the text \"Red\", \"Green\", and \"Blue\" when we are debugging.\n",
"\n",
"IHaskell lets you define a custom display mechanism for any data type via its `IHaskellDisplay` typeclass. Since you can use IHaskell in console mode as well as notebook mode, you can provide a list of display outputs for any data type, and the frontend will simply choose the best one. Here's how you would implement a very simple display mechanism for this `Color` data type:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import IHaskell.Display\n",
"\n",
"instance IHaskellDisplay Color where\n",
" display color = return [html code]\n",
" where\n",
" code = concat [\"<div style='font-weight: bold; color:\"\n",
" , css color\n",
" , \"'>Look!</div>\"]\n",
" css Red = \"red\"\n",
" css Blue = \"blue\"\n",
" css Green = \"green\""
],
"language": "python",
"metadata": {},
"outputs": [],
"prompt_number": 16
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Once we define a custom `display :: a -> IO [DisplayData]` function, we can simply output a `Color`:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"Red\n",
"Green\n",
"Blue"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style='font-weight: bold; color:red'>Look!</div>"
],
"metadata": {},
"output_type": "display_data"
},
{
"html": [
"<div style='font-weight: bold; color:green'>Look!</div>"
],
"metadata": {},
"output_type": "display_data"
},
{
"html": [
"<div style='font-weight: bold; color:blue'>Look!</div>"
],
"metadata": {},
"output_type": "display_data"
}
],
"prompt_number": 17
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `DisplayData` type has several constructors which let you display your data as plain text, HTML, images (SVG, PNG, JPG), or even as LaTeX code.\n",
"\n",
"In order to ship an extension for IHaskell, simply create a package named `ihaskell-thing` with a module named `IHaskell.Display.Thing`. As long as `ihaskell-thing` is installed, IHaskell will detect and use it automatically.\n",
"\n",
"A number of packages already exist, which we can briefly look at. First, in `ihaskell-basic`, we have very simple displays for data types from `Prelude`."
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- We can display Maybes fancily for Show-able types.\n",
"Just ()\n",
"Nothing\n",
"\n",
"-- But it dies if it's not showable.\n",
"data NoShow = X Int\n",
"Just (X 3)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<span style='color: green; font-weight: bold;'>Just</span><span style='font-family: monospace;'>()</span>"
],
"metadata": {},
"output_type": "display_data",
"text": [
"Just ()"
]
},
{
"html": [
"<span style='color: red; font-weight: bold;'>Nothing</span>"
],
"metadata": {},
"output_type": "display_data",
"text": [
"Nothing"
]
},
{
"html": [
2014-01-09 12:39:50 -05:00
"<div class='collapse-group'><span class='btn' href='#' id='unshowable'>Unshowable:<span class='show-type'>NoShow</span></span><span class='err-msg collapse'>No instance for (Show NoShow) arising from a use of `print'<br/>Possible fix: add an instance declaration for (Show NoShow)<br/>In a stmt of an interactive GHCi command: print it</span></div><script>$('#unshowable').on('click', function(e) {\n",
" e.preventDefault();\n",
" var $this = $(this);\n",
" var $collapse = $this.closest('.collapse-group').find('.err-msg');\n",
" $collapse.collapse('toggle');\n",
"});\n",
"</script>"
2013-12-30 17:18:10 -05:00
],
"metadata": {},
"output_type": "display_data",
"text": [
2014-01-09 12:39:50 -05:00
"No instance for (Show NoShow) arising from a use of `print'\n",
"Possible fix: add an instance declaration for (Show NoShow)\n",
"In a stmt of an interactive GHCi command: print it"
2013-12-30 17:18:10 -05:00
]
}
],
2014-01-09 13:34:00 -05:00
"prompt_number": 18
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `ihaskell-aeson` package adds a display for [Aeson](http://hackage.haskell.org/package/aeson) JSON `Value` types. These are automatically syntax highlighted and formatted nicely."
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- Aeson JSON data types are displayed nicely.\n",
":ext OverloadedStrings\n",
"\n",
"import Data.Aeson\n",
"\n",
"data Coord = Coord { x :: Double, y :: Double }\n",
"instance ToJSON Coord where\n",
" toJSON (Coord x y) = object [\"x\" .= x, \"y\" .= y]\n",
"\n",
"Null\n",
"Bool True\n",
"toJSON (Coord 3 2)"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div class=\"highlight-code\" id=\"javascript\">null</div>"
],
"metadata": {},
"output_type": "display_data",
"text": [
"null"
]
},
{
"html": [
"<div class=\"highlight-code\" id=\"javascript\">true</div>"
],
"metadata": {},
"output_type": "display_data",
"text": [
"true"
]
},
{
"html": [
"<div class=\"highlight-code\" id=\"javascript\">{\n",
" \"x\": 3.0,\n",
" \"y\": 2.0\n",
"}</div>"
],
"metadata": {},
"output_type": "display_data",
"text": [
"{\n",
" \"x\": 3.0,\n",
" \"y\": 2.0\n",
"}"
]
}
],
2014-01-09 13:34:00 -05:00
"prompt_number": 19
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `ihaskell-blaze` package lets you play around with HTML straight from within IHaskell using the [Blaze](http://jaspervdj.be/blaze/tutorial.html) library."
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- Small bits of HTML generated via Blaze are displayed.\n",
"import Prelude hiding (div, id)\n",
"import Text.Blaze.Html4.Strict hiding (map, style)\n",
"import Text.Blaze.Html4.Strict.Attributes\n",
"\n",
"div ! style \"color: red\" $ do\n",
" p \"This is an example of BlazeMarkup syntax.\"\n",
" b \"Hello\"\n",
" \n",
"forM [1..5] $ \\size -> do\n",
" let s = toValue $ size * 80\n",
" img ! src \"/static/base/images/ipynblogo.png\" ! width s"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<div style=\"color: red\">\n",
" <p>\n",
" This is an example of BlazeMarkup syntax.\n",
" </p>\n",
" <b>\n",
" Hello\n",
" </b>\n",
"</div>\n"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<div style=\"color: red\">\n",
" <p>\n",
" This is an example of BlazeMarkup syntax.\n",
" </p>\n",
" <b>\n",
" Hello\n",
" </b>\n",
"</div>"
]
},
{
"html": [
"<img src=\"/static/base/images/ipynblogo.png\" width=\"80\">\n",
"<img src=\"/static/base/images/ipynblogo.png\" width=\"160\">\n",
"<img src=\"/static/base/images/ipynblogo.png\" width=\"240\">\n",
"<img src=\"/static/base/images/ipynblogo.png\" width=\"320\">\n",
"<img src=\"/static/base/images/ipynblogo.png\" width=\"400\">\n"
],
"metadata": {},
"output_type": "display_data",
"text": [
"<img src=\"/static/base/images/ipynblogo.png\" width=\"80\">\n",
"<img src=\"/static/base/images/ipynblogo.png\" width=\"160\">\n",
"<img src=\"/static/base/images/ipynblogo.png\" width=\"240\">\n",
"<img src=\"/static/base/images/ipynblogo.png\" width=\"320\">\n",
"<img src=\"/static/base/images/ipynblogo.png\" width=\"400\">"
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 20
2014-01-09 13:34:00 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `ihaskell-diagrams` package allows you to experiment with the [diagrams](http://projects.haskell.org/diagrams/) package. It requires the Cairo backend."
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- We can draw diagrams, right in the notebook.\n",
":extension NoMonomorphismRestriction\n",
"import Diagrams.Prelude\n",
"\n",
"-- By Brent Yorgey\n",
"-- Draw a Sierpinski triangle!\n",
"sierpinski 1 = eqTriangle 1\n",
"sierpinski n = s\n",
" ===\n",
" (s ||| s) # centerX\n",
" where s = sierpinski (n-1)\n",
"\n",
"-- The `diagram` function is used to display them in the notebook.\n",
"diagram $ sierpinski 4\n",
" # centerXY\n",
" # fc black\n",
" `atop` square 10\n",
" # fc white"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
2014-01-09 12:39:50 -05:00
"png": "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
"svg": [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"300pt\" height=\"300pt\" viewBox=\"0 0 300 300\" version=\"1.1\">\n",
"<g id=\"surface2\">\n",
"<path style=\"fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 5 5 L 5 -5 L -5 -5 L -5 5 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 4 3.464063 L 3.5 2.598047 L 3 3.464063 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 3 3.464063 L 2.5 2.598047 L 2 3.464063 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 3.5 2.598047 L 3 1.732031 L 2.5 2.598047 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 2 3.464063 L 1.5 2.598047 L 1 3.464063 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 1 3.464063 L 0.5 2.598047 L -0.000000000000002665 3.464063 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 1.5 2.598047 L 1 1.732031 L 0.5 2.598047 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 3 1.732031 L 2.5 0.866016 L 2 1.732031 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 2 1.732031 L 1.5 0.866016 L 1 1.732031 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 2.5 0.866016 L 2 0 L 1.5 0.866016 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -0.000000000000002665 3.464063 L -0.5 2.598047 L -1 3.464063 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -1 3.464063 L -1.5 2.598047 L -2 3.464063 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -0.5 2.598047 L -1 1.732031 L -1.5 2.598047 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -2 3.464063 L -2.5 2.598047 L -3 3.464063 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -3 3.464063 L -3.5 2.598047 L -4 3.464063 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -2.5 2.598047 L -3 1.732031 L -3.5 2.598047 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -1 1.732031 L -1.5 0.866016 L -2 1.732031 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -2 1.732031 L -2.5 0.866016 L -3 1.732031 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -1.5 0.866016 L -2 0 L -2.5 0.866016 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 2 0 L 1.5 -0.866016 L 1 0 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 1 0 L 0.5 -0.866016 L -0.000000000000002665 0 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 1.5 -0.866016 L 1 -1.732031 L 0.5 -0.866016 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -0.000000000000002665 0 L -0.5 -0.866016 L -1 0 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -1 0 L -1.5 -0.866016 L -2 0 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -0.5 -0.866016 L -1 -1.732031 L -1.5 -0.866016 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 1 -1.732031 L 0.5 -2.598047 L -0.000000000000002665 -1.732031 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M -0.000000000000002665 -1.732031 L -0.5 -2.598047 L -1 -1.732031 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;stroke-width:0.01;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 0.5 -2.598047 L -0.000000000000002665 -3.464062 L -0.5 -2.598047 Z \" transform=\"matrix(30,0,0,30,150,150)\"/>\n",
"</g>\n",
"</svg>\n"
]
2013-12-30 17:18:10 -05:00
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 21
2014-01-09 13:34:00 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Just like with Diagrams, `ihaskell-chart` allows you to use the [Chart](https://github.com/timbod7/haskell-chart/wiki) library for plotting from within IHaskell."
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- We can draw small charts in the notebook.\n",
"-- This example is taken from the haskell-chart documentation.\n",
"import Graphics.Rendering.Chart \n",
"import Data.Default.Class\n",
"import Control.Lens\n",
"\n",
"let values = [\n",
" (\"Mexico City\" , 19.2, 0),\n",
" (\"Mumbai\" , 12.9, 10), \n",
" (\"Sydney\" , 4.3, 0),\n",
" (\"London\" , 8.3, 0), \n",
" (\"New York\" , 8.2, 25)]\n",
" \n",
"pitem (s, v, o) = pitem_value .~ v\n",
" $ pitem_label .~ s\n",
" $ pitem_offset .~ o\n",
" $ def \n",
"\n",
"-- Convert to a renderable in order to display it.\n",
"toRenderable \n",
" $ pie_title .~ \"Relative Population\"\n",
" $ pie_plot . pie_data .~ map pitem values\n",
" $ def"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
2014-01-09 12:39:50 -05:00
"png": "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
"svg": [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"450pt\" height=\"300pt\" viewBox=\"0 0 450 300\" version=\"1.1\">\n",
"<defs>\n",
"<g>\n",
"<symbol overflow=\"visible\" id=\"glyph0-0\">\n",
"<path style=\"stroke:none;\" d=\"\"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-1\">\n",
"<path style=\"stroke:none;\" d=\"M 3.398438 -8.921875 L 3.398438 -6.019531 L 5.953125 -6.019531 C 6.460938 -6.019531 6.84375 -6.078125 7.097656 -6.195312 C 7.546875 -6.402344 7.769531 -6.804688 7.769531 -7.414062 C 7.769531 -8.066406 7.554688 -8.507812 7.117188 -8.730469 C 6.875 -8.859375 6.507812 -8.921875 6.019531 -8.921875 Z M 8.234375 -10.515625 C 8.644531 -10.347656 8.988281 -10.09375 9.273438 -9.761719 C 9.507812 -9.488281 9.691406 -9.1875 9.828125 -8.855469 C 9.964844 -8.523438 10.035156 -8.144531 10.035156 -7.71875 C 10.035156 -7.207031 9.90625 -6.703125 9.644531 -6.207031 C 9.386719 -5.710938 8.960938 -5.359375 8.363281 -5.15625 C 8.863281 -4.957031 9.214844 -4.671875 9.421875 -4.304688 C 9.628906 -3.933594 9.734375 -3.371094 9.734375 -2.613281 L 9.734375 -1.890625 C 9.734375 -1.398438 9.753906 -1.0625 9.792969 -0.886719 C 9.851562 -0.609375 9.988281 -0.402344 10.203125 -0.269531 L 10.203125 0 L 7.71875 0 C 7.652344 -0.238281 7.601562 -0.433594 7.574219 -0.578125 C 7.515625 -0.882812 7.484375 -1.191406 7.476562 -1.507812 L 7.464844 -2.511719 C 7.453125 -3.199219 7.328125 -3.660156 7.085938 -3.890625 C 6.84375 -4.117188 6.390625 -4.234375 5.726562 -4.234375 L 3.398438 -4.234375 L 3.398438 0 L 1.195312 0 L 1.195312 -10.796875 L 6.488281 -10.796875 C 7.246094 -10.78125 7.828125 -10.6875 8.234375 -10.515625 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-2\">\n",
"<path style=\"stroke:none;\" d=\"M 3 -6.019531 C 2.734375 -5.71875 2.566406 -5.308594 2.496094 -4.789062 L 5.742188 -4.789062 C 5.707031 -5.339844 5.539062 -5.761719 5.242188 -6.046875 C 4.941406 -6.332031 4.566406 -6.476562 4.125 -6.476562 C 3.640625 -6.476562 3.265625 -6.324219 3 -6.019531 Z M 5.917969 -7.820312 C 6.449219 -7.574219 6.890625 -7.179688 7.234375 -6.644531 C 7.546875 -6.171875 7.75 -5.621094 7.84375 -4.996094 C 7.898438 -4.628906 7.921875 -4.101562 7.910156 -3.414062 L 2.445312 -3.414062 C 2.476562 -2.613281 2.726562 -2.050781 3.199219 -1.726562 C 3.488281 -1.527344 3.835938 -1.429688 4.242188 -1.429688 C 4.671875 -1.429688 5.019531 -1.550781 5.289062 -1.792969 C 5.433594 -1.925781 5.5625 -2.109375 5.675781 -2.34375 L 7.808594 -2.34375 C 7.753906 -1.871094 7.507812 -1.390625 7.066406 -0.902344 C 6.382812 -0.125 5.425781 0.265625 4.195312 0.265625 C 3.179688 0.265625 2.285156 -0.0625 1.507812 -0.71875 C 0.730469 -1.371094 0.34375 -2.4375 0.34375 -3.910156 C 0.34375 -5.292969 0.695312 -6.351562 1.394531 -7.089844 C 2.09375 -7.828125 3.003906 -8.195312 4.125 -8.195312 C 4.789062 -8.195312 5.386719 -8.070312 5.917969 -7.820312 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-3\">\n",
"<path style=\"stroke:none;\" d=\"M 3.105469 0 L 1.019531 0 L 1.019531 -10.796875 L 3.105469 -10.796875 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-4\">\n",
"<path style=\"stroke:none;\" d=\"M 5.375 -3.882812 C 5.242188 -3.800781 5.109375 -3.730469 4.976562 -3.679688 C 4.84375 -3.628906 4.65625 -3.582031 4.421875 -3.539062 L 3.953125 -3.449219 C 3.515625 -3.371094 3.199219 -3.277344 3.011719 -3.164062 C 2.6875 -2.972656 2.527344 -2.679688 2.527344 -2.277344 C 2.527344 -1.921875 2.625 -1.664062 2.824219 -1.503906 C 3.023438 -1.347656 3.261719 -1.265625 3.546875 -1.265625 C 3.996094 -1.265625 4.40625 -1.398438 4.785156 -1.664062 C 5.164062 -1.925781 5.359375 -2.40625 5.375 -3.105469 Z M 4.109375 -4.855469 C 4.496094 -4.90625 4.769531 -4.964844 4.9375 -5.039062 C 5.234375 -5.164062 5.382812 -5.363281 5.382812 -5.632812 C 5.382812 -5.960938 5.269531 -6.183594 5.042969 -6.308594 C 4.816406 -6.433594 4.484375 -6.496094 4.042969 -6.496094 C 3.550781 -6.496094 3.199219 -6.375 2.996094 -6.128906 C 2.847656 -5.949219 2.75 -5.707031 2.703125 -5.398438 L 0.6875 -5.398438 C 0.730469 -6.097656 0.929688 -6.671875 1.273438 -7.117188 C 1.824219 -7.820312 2.773438 -8.171875 4.117188 -8.171875 C 4.992188 -8.171875 5.765625 -8 6.445312 -7.652344 C 7.125 -7.304688 7.464844 -6.652344 7.464844 -5.691406 L 7.464844 -2.027344 C 7.464844 -1.773438 7.46875 -1.46875 7.476562 -1.105469 C 7.492188 -0.832031 7.535156 -0.648438 7.601562 -0.550781 C 7.671875 -0.453125 7.773438 -0.371094 7.910156 -0.308594 L 7.910156 0 L 5.640625 0 C 5.578125 -0.160156 5.53125 -0.3125 5.507812 -0.453125 C 5.484375 -0.59375 5.464844 -0.757812 5.449219 -0.9375 C 5.160156 -0.625 4.828125 -0.359375 4.453125 -0.140625 C 4.003906 0.117188 3.496094 0.25 2.929688 0.25 C 2.207031 0.25 1.609375 0.0429688 1.140625 -0.371094 C 0.667969 -0.78125 0.433594 -1.367188 0.433594 -2.125 C 0.433594 -3.105469 0.8125 -3.816406 1.566406 -4.253906 C 1.980469 -4.492188 2.59375 -4.664062 3.398438 -4.769531 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-5\">\n",
"<path style=\"stroke:none;\" d=\"M 0.152344 -6.421875 L 0.152344 -7.910156 L 1.265625 -7.910156 L 1.265625 -10.136719 L 3.332031 -10.136719 L 3.332031 -7.910156 L 4.628906 -7.910156 L 4.628906 -6.421875 L 3.332031 -6.421875 L 3.332031 -2.203125 C 3.332031 -1.875 3.375 -1.671875 3.457031 -1.59375 C 3.539062 -1.511719 3.792969 -1.472656 4.21875 -1.472656 C 4.28125 -1.472656 4.347656 -1.472656 4.421875 -1.476562 C 4.492188 -1.476562 4.5625 -1.480469 4.628906 -1.488281 L 4.628906 0.0742188 L 3.640625 0.109375 C 2.652344 0.144531 1.980469 -0.0273438 1.617188 -0.402344 C 1.382812 -0.640625 1.265625 -1.011719 1.265625 -1.507812 L 1.265625 -6.421875 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-6\">\n",
"<path style=\"stroke:none;\" d=\"M 3.121094 -8.9375 L 1.003906 -8.9375 L 1.003906 -10.863281 L 3.121094 -10.863281 Z M 1.003906 -7.984375 L 3.121094 -7.984375 L 3.121094 0 L 1.003906 0 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-7\">\n",
"<path style=\"stroke:none;\" d=\"M 5.894531 -7.984375 L 8.136719 -7.984375 L 5.257812 0 L 3.054688 0 L 0.191406 -7.984375 L 2.535156 -7.984375 L 4.195312 -2.09375 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-8\">\n",
"<path style=\"stroke:none;\" d=\"\"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-9\">\n",
"<path style=\"stroke:none;\" d=\"M 6.777344 -8.5625 C 6.484375 -8.800781 6.070312 -8.921875 5.539062 -8.921875 L 3.433594 -8.921875 L 3.433594 -5.742188 L 5.539062 -5.742188 C 6.070312 -5.742188 6.484375 -5.871094 6.777344 -6.128906 C 7.074219 -6.390625 7.222656 -6.800781 7.222656 -7.359375 C 7.222656 -7.921875 7.074219 -8.324219 6.777344 -8.5625 Z M 8.488281 -4.671875 C 7.84375 -4.144531 6.921875 -3.882812 5.726562 -3.882812 L 3.433594 -3.882812 L 3.433594 0 L 1.195312 0 L 1.195312 -10.796875 L 5.894531 -10.796875 C 6.980469 -10.796875 7.84375 -10.515625 8.488281 -9.960938 C 9.132812 -9.40625 9.457031 -8.542969 9.457031 -7.375 C 9.457031 -6.101562 9.132812 -5.199219 8.488281 -4.671875 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-10\">\n",
"<path style=\"stroke:none;\" d=\"M 5.960938 -2.125 C 6.289062 -2.558594 6.453125 -3.175781 6.453125 -3.976562 C 6.453125 -4.777344 6.289062 -5.394531 5.960938 -5.828125 C 5.632812 -6.257812 5.164062 -6.476562 4.554688 -6.476562 C 3.945312 -6.476562 3.476562 -6.257812 3.144531 -5.828125 C 2.816406 -5.394531 2.652344 -4.777344 2.652344 -3.976562 C 2.652344 -3.175781 2.816406 -2.558594 3.144531 -2.125 C 3.476562 -1.691406 3.945312 -1.472656 4.554688 -1.472656 C 5.164062 -1.472656 5.632812 -1.6875 5.960938 -2.125 Z M 7.632812 -0.96875 C 6.957031 -0.136719 5.933594 0.277344 4.5625 0.277344 C 3.191406 0.277344 2.167969 -0.136719 1.492188 -0.96875 C 0.820312 -1.800781 0.484375 -2.804688 0.484375 -3.976562 C 0.484375 -5.128906 0.820312 -6.128906 1.492188 -6.972656 C 2.167969 -7.816406 3.191406 -8.238281 4.5625 -8.238281 C 5.933594 -8.238281 6.957031 -7.816406 7.632812 -6.972656 C 8.304688 -6.128906 8.640625 -5.128906 8.640625 -3.976562 C 8.640625 -2.804688 8.304688 -1.804688 7.632812 -0.96875 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-11\">\n",
"<path style=\"stroke:none;\" d=\"M 6.054688 -5.625 C 5.773438 -6.097656 5.316406 -6.335938 4.6875 -6.335938 C 3.929688 -6.335938 3.410156 -5.976562 3.128906 -5.257812 C 2.980469 -4.878906 2.90625 -4.394531 2.90625 -3.808594 C 2.90625 -2.882812 3.15625 -2.230469 3.648438 -1.851562 C 3.941406 -1.632812 4.289062 -1.523438 4.6875 -1.523438 C 5.269531 -1.523438 5.710938 -1.75 6.015625 -2.195312 C 6.320312 -2.644531 6.476562 -3.246094 6.476562 -3.992188 C 6.476562 -4.605469 6.335938 -5.152344 6.054688 -5.625 Z M 7.65625 -7.125 C 8.304688 -6.4375 8.628906 -5.425781 8.628906 -4.09375 C 8.628906 -2.6875 8.3125 -1.617188 7.679688 -0.878906 C 7.046875 -0.140625 6.234375 0.226562 5.238281 0.226562 C 4.601562 0.226562 4.074219 0.0703125 3.65625 -0.25 C 3.425781 -0.425781 3.199219 -0.679688 2.980469 -1.019531 L 2.980469 3.140625 L 0.914062 3.140625 L 0.914062 -7.984375 L 2.914062 -7.984375 L 2.914062 -6.804688 C 3.140625 -7.152344 3.378906 -7.425781 3.632812 -7.625 C 4.097656 -7.980469 4.648438 -8.160156 5.289062 -8.160156 C 6.222656 -8.160156 7.011719 -7.816406 7.65625 -7.125 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-12\">\n",
"<path style=\"stroke:none;\" d=\"M 3.054688 -7.984375 L 3.054688 -3.171875 C 3.054688 -2.71875 3.109375 -2.375 3.214844 -2.144531 C 3.40625 -1.742188 3.78125 -1.539062 4.335938 -1.539062 C 5.046875 -1.539062 5.539062 -1.828125 5.800781 -2.402344 C 5.9375 -2.714844 6.007812 -3.128906 6.007812 -3.640625 L 6.007812 -7.984375 L 8.121094 -7.984375 L 8.121094 0 L 6.09375 0 L 6.09375 -1.128906 C 6.074219 -1.105469 6.023438 -1.03125 5.945312 -0.90625 C 5.867188 -0.785156 5.777344 -0.679688 5.667969 -0.585938 C 5.339844 -0.292969 5.027344 -0.09375 4.71875 0.015625 C 4.414062 0.121094 4.058594 0.175781 3.648438 0.175781 C 2.464844 0.175781 1.671875 -0.25 1.257812 -1.097656 C 1.03125 -1.566406 0.914062 -2.257812 0.914062 -3.171875 L 0.914062 -7.984375 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph0-13\">\n",
"<path style=\"stroke:none;\" d=\"M 7.421875 -7.527344 C 7.949219 -7.09375 8.210938 -6.375 8.210938 -5.375 L 8.210938 0 L 6.070312 0 L 6.070312 -4.855469 C 6.070312 -5.277344 6.015625 -5.597656 5.902344 -5.824219 C 5.699219 -6.234375 5.308594 -6.4375 4.730469 -6.4375 C 4.023438 -6.4375 3.539062 -6.136719 3.273438 -5.539062 C 3.136719 -5.21875 3.070312 -4.8125 3.070312 -4.320312 L 3.070312 0 L 0.988281 0 L 0.988281 -7.96875 L 3.003906 -7.96875 L 3.003906 -6.804688 C 3.273438 -7.214844 3.523438 -7.507812 3.765625 -7.691406 C 4.195312 -8.011719 4.738281 -8.171875 5.398438 -8.171875 C 6.222656 -8.171875 6.898438 -7.957031 7.421875 -7.527344 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-0\">\n",
"<path style=\"stroke:none;\" d=\"\"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-1\">\n",
"<path style=\"stroke:none;\" d=\"M 0.738281 -7.171875 L 2.128906 -7.171875 L 4.1875 -1.109375 L 6.234375 -7.171875 L 7.613281 -7.171875 L 7.613281 0 L 6.6875 0 L 6.6875 -4.234375 C 6.6875 -4.378906 6.691406 -4.621094 6.699219 -4.960938 C 6.707031 -5.300781 6.710938 -5.664062 6.710938 -6.050781 L 4.664062 0 L 3.703125 0 L 1.640625 -6.050781 L 1.640625 -5.828125 C 1.640625 -5.652344 1.644531 -5.386719 1.652344 -5.027344 C 1.660156 -4.667969 1.664062 -4.402344 1.664062 -4.234375 L 1.664062 0 L 0.738281 0 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-2\">\n",
"<path style=\"stroke:none;\" d=\"M 3.902344 -5.085938 C 4.25 -4.910156 4.515625 -4.6875 4.695312 -4.410156 C 4.871094 -4.144531 4.992188 -3.835938 5.046875 -3.484375 C 5.101562 -3.246094 5.125 -2.859375 5.125 -2.335938 L 1.292969 -2.335938 C 1.308594 -1.804688 1.4375 -1.378906 1.671875 -1.058594 C 1.90625 -0.738281 2.265625 -0.578125 2.757812 -0.578125 C 3.21875 -0.578125 3.585938 -0.726562 3.859375 -1.03125 C 4.015625 -1.207031 4.125 -1.410156 4.1875 -1.640625 L 5.054688 -1.640625 C 5.03125 -1.449219 4.957031 -1.234375 4.828125 -1 C 4.699219 -0.761719 4.554688 -0.570312 4.394531 -0.421875 C 4.128906 -0.160156 3.796875 0.015625 3.402344 0.109375 C 3.191406 0.160156 2.953125 0.1875 2.6875 0.1875 C 2.035156 0.1875 1.484375 -0.0507812 1.03125 -0.523438 C 0.578125 -1 0.351562 -1.660156 0.351562 -2.515625 C 0.351562 -3.355469 0.578125 -4.035156 1.035156 -4.5625 C 1.492188 -5.085938 2.085938 -5.347656 2.820312 -5.347656 C 3.191406 -5.347656 3.554688 -5.257812 3.902344 -5.085938 Z M 4.222656 -3.03125 C 4.1875 -3.414062 4.105469 -3.71875 3.976562 -3.945312 C 3.734375 -4.367188 3.332031 -4.578125 2.769531 -4.578125 C 2.367188 -4.578125 2.027344 -4.433594 1.753906 -4.144531 C 1.480469 -3.851562 1.335938 -3.480469 1.320312 -3.03125 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-3\">\n",
"<path style=\"stroke:none;\" d=\"M 0.148438 -5.230469 L 1.285156 -5.230469 L 2.484375 -3.390625 L 3.703125 -5.230469 L 4.769531 -5.203125 L 3.007812 -2.679688 L 4.847656 0 L 3.726562 0 L 2.425781 -1.960938 L 1.167969 0 L 0.0546875 0 L 1.894531 -2.679688 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-4\">\n",
"<path style=\"stroke:none;\" d=\"M 0.644531 -5.203125 L 1.539062 -5.203125 L 1.539062 0 L 0.644531 0 Z M 0.644531 -7.171875 L 1.539062 -7.171875 L 1.539062 -6.175781 L 0.644531 -6.175781 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-5\">\n",
"<path style=\"stroke:none;\" d=\"M 4.097656 -4.953125 C 4.46875 -4.664062 4.691406 -4.171875 4.765625 -3.472656 L 3.910156 -3.472656 C 3.859375 -3.792969 3.742188 -4.0625 3.554688 -4.273438 C 3.367188 -4.488281 3.070312 -4.59375 2.660156 -4.59375 C 2.101562 -4.59375 1.699219 -4.320312 1.460938 -3.773438 C 1.304688 -3.417969 1.226562 -2.980469 1.226562 -2.460938 C 1.226562 -1.9375 1.335938 -1.496094 1.558594 -1.136719 C 1.78125 -0.78125 2.128906 -0.601562 2.601562 -0.601562 C 2.96875 -0.601562 3.257812 -0.710938 3.46875 -0.933594 C 3.683594 -1.15625 3.828125 -1.464844 3.910156 -1.851562 L 4.765625 -1.851562 C 4.667969 -1.15625 4.421875 -0.648438 4.03125 -0.328125 C 3.640625 -0.0078125 3.144531 0.152344 2.535156 0.152344 C 1.851562 0.152344 1.304688 -0.0976562 0.898438 -0.597656 C 0.492188 -1.097656 0.289062 -1.722656 0.289062 -2.46875 C 0.289062 -3.386719 0.511719 -4.101562 0.957031 -4.613281 C 1.402344 -5.125 1.972656 -5.382812 2.660156 -5.382812 C 3.25 -5.382812 3.730469 -5.238281 4.097656 -4.953125 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-6\">\n",
"<path style=\"stroke:none;\" d=\"M 3.917969 -1.226562 C 4.132812 -1.667969 4.242188 -2.160156 4.242188 -2.699219 C 4.242188 -3.1875 4.164062 -3.585938 4.007812 -3.890625 C 3.761719 -4.375 3.335938 -4.613281 2.730469 -4.613281 C 2.191406 -4.613281 1.800781 -4.410156 1.558594 -4 C 1.3125 -3.589844 1.191406 -3.09375 1.191406 -2.515625 C 1.191406 -1.957031 1.3125 -1.492188 1.558594 -1.125 C 1.800781 -0.753906 2.1875 -0.566406 2.71875 -0.566406 C 3.300781 -0.566406 3.703125 -0.785156 3.917969 -1.226562 Z M 4.460938 -4.707031 C 4.929688 -4.257812 5.160156 -3.597656 5.160156 -2.726562 C 5.160156 -1.882812 4.957031 -1.183594 4.546875 -0.632812 C 4.136719 -0.0859375 3.5 0.191406 2.636719 0.191406 C 1.917969 0.191406 1.347656 -0.0546875 0.921875 -0.539062 C 0.5 -1.027344 0.289062 -1.679688 0.289062 -2.5 C 0.289062 -3.378906 0.511719 -4.078125 0.957031 -4.601562 C 1.402344 -5.121094 2 -5.382812 2.753906 -5.382812 C 3.429688 -5.382812 3.996094 -5.15625 4.460938 -4.707031 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-7\">\n",
"<path style=\"stroke:none;\" d=\"\"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-8\">\n",
"<path style=\"stroke:none;\" d=\"M 5.898438 -6.648438 C 6.398438 -6.171875 6.679688 -5.628906 6.734375 -5.019531 L 5.785156 -5.019531 C 5.679688 -5.480469 5.464844 -5.847656 5.144531 -6.117188 C 4.824219 -6.386719 4.375 -6.523438 3.792969 -6.523438 C 3.085938 -6.523438 2.515625 -6.273438 2.082031 -5.777344 C 1.648438 -5.28125 1.429688 -4.523438 1.429688 -3.496094 C 1.429688 -2.65625 1.625 -1.976562 2.019531 -1.453125 C 2.410156 -0.929688 2.996094 -0.667969 3.773438 -0.667969 C 4.492188 -0.667969 5.035156 -0.945312 5.410156 -1.492188 C 5.609375 -1.78125 5.757812 -2.164062 5.855469 -2.636719 L 6.800781 -2.636719 C 6.71875 -1.882812 6.4375 -1.25 5.960938 -0.738281 C 5.390625 -0.121094 4.625 0.1875 3.65625 0.1875 C 2.824219 0.1875 2.125 -0.0664062 1.558594 -0.570312 C 0.8125 -1.238281 0.4375 -2.269531 0.4375 -3.664062 C 0.4375 -4.71875 0.71875 -5.585938 1.28125 -6.265625 C 1.886719 -7 2.71875 -7.367188 3.785156 -7.367188 C 4.691406 -7.367188 5.398438 -7.128906 5.898438 -6.648438 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-9\">\n",
"<path style=\"stroke:none;\" d=\"M 0.820312 -6.6875 L 1.710938 -6.6875 L 1.710938 -5.230469 L 2.542969 -5.230469 L 2.542969 -4.511719 L 1.710938 -4.511719 L 1.710938 -1.097656 C 1.710938 -0.914062 1.769531 -0.792969 1.894531 -0.734375 C 1.960938 -0.695312 2.078125 -0.679688 2.234375 -0.679688 C 2.277344 -0.679688 2.324219 -0.679688 2.375 -0.679688 C 2.421875 -0.683594 2.480469 -0.6875 2.542969 -0.695312 L 2.542969 0 C 2.441406 0.03125 2.339844 0.0507812 2.230469 0.0625 C 2.121094 0.078125 2 0.0820312 1.875 0.0820312 C 1.464844 0.0820312 1.1875 -0.0234375 1.039062 -0.230469 C 0.894531 -0.441406 0.820312 -0.714844 0.820312 -1.050781 L 0.820312 -4.511719 L 0.113281 -4.511719 L 0.113281 -5.230469 L 0.820312 -5.230469 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-10\">\n",
"<path style=\"stroke:none;\" d=\"M 3.910156 -5.230469 L 4.882812 -5.230469 C 4.757812 -4.894531 4.484375 -4.128906 4.058594 -2.933594 C 3.738281 -2.035156 3.472656 -1.304688 3.257812 -0.738281 C 2.75 0.597656 2.390625 1.410156 2.183594 1.703125 C 1.976562 1.996094 1.617188 2.144531 1.109375 2.144531 C 0.984375 2.144531 0.890625 2.140625 0.824219 2.128906 C 0.757812 2.117188 0.671875 2.101562 0.578125 2.074219 L 0.578125 1.273438 C 0.730469 1.316406 0.839844 1.34375 0.90625 1.351562 C 0.976562 1.363281 1.035156 1.367188 1.089844 1.367188 C 1.25 1.367188 1.371094 1.339844 1.449219 1.285156 C 1.523438 1.234375 1.589844 1.167969 1.640625 1.089844 C 1.65625 1.0625 1.714844 0.929688 1.816406 0.6875 C 1.917969 0.445312 1.992188 0.269531 2.035156 0.152344 L 0.101562 -5.230469 L 1.097656 -5.230469 L 2.5 -0.972656 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-11\">\n",
"<path style=\"stroke:none;\" d=\"M 1.523438 -5.230469 L 1.523438 -1.757812 C 1.523438 -1.492188 1.566406 -1.273438 1.648438 -1.101562 C 1.804688 -0.789062 2.097656 -0.632812 2.523438 -0.632812 C 3.136719 -0.632812 3.554688 -0.90625 3.773438 -1.453125 C 3.894531 -1.746094 3.953125 -2.148438 3.953125 -2.660156 L 3.953125 -5.230469 L 4.835938 -5.230469 L 4.835938 0 L 4.003906 0 L 4.015625 -0.773438 C 3.898438 -0.574219 3.757812 -0.40625 3.589844 -0.269531 C 3.253906 0.00390625 2.847656 0.140625 2.367188 0.140625 C 1.621094 0.140625 1.113281 -0.109375 0.84375 -0.605469 C 0.699219 -0.871094 0.625 -1.230469 0.625 -1.675781 L 0.625 -5.230469 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-12\">\n",
"<path style=\"stroke:none;\" d=\"M 0.644531 -5.230469 L 1.515625 -5.230469 L 1.515625 -4.488281 C 1.722656 -4.746094 1.910156 -4.929688 2.078125 -5.046875 C 2.367188 -5.246094 2.699219 -5.347656 3.066406 -5.347656 C 3.484375 -5.347656 3.820312 -5.242188 4.070312 -5.039062 C 4.214844 -4.921875 4.34375 -4.75 4.460938 -4.523438 C 4.65625 -4.800781 4.886719 -5.007812 5.152344 -5.144531 C 5.414062 -5.28125 5.710938 -5.347656 6.039062 -5.347656 C 6.742188 -5.347656 7.222656 -5.09375 7.476562 -4.585938 C 7.613281 -4.3125 7.679688 -3.945312 7.679688 -3.480469 L 7.679688 0 L 6.765625 0 L 6.765625 -3.632812 C 6.765625 -3.980469 6.679688 -4.21875 6.507812 -4.351562 C 6.332031 -4.480469 6.121094 -4.546875 5.867188 -4.546875 C 5.523438 -4.546875 5.226562 -4.429688 4.976562 -4.199219 C 4.726562 -3.96875 4.605469 -3.582031 4.605469 -3.042969 L 4.605469 0 L 3.710938 0 L 3.710938 -3.414062 C 3.710938 -3.769531 3.667969 -4.027344 3.585938 -4.1875 C 3.453125 -4.433594 3.203125 -4.554688 2.835938 -4.554688 C 2.503906 -4.554688 2.203125 -4.425781 1.929688 -4.171875 C 1.660156 -3.914062 1.523438 -3.445312 1.523438 -2.773438 L 1.523438 0 L 0.644531 0 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-13\">\n",
"<path style=\"stroke:none;\" d=\"M 0.578125 -7.195312 L 1.429688 -7.195312 L 1.429688 -4.59375 C 1.621094 -4.84375 1.851562 -5.035156 2.117188 -5.167969 C 2.386719 -5.300781 2.675781 -5.367188 2.988281 -5.367188 C 3.640625 -5.367188 4.167969 -5.140625 4.574219 -4.695312 C 4.976562 -4.246094 5.179688 -3.585938 5.179688 -2.714844 C 5.179688 -1.886719 4.980469 -1.203125 4.578125 -0.65625 C 4.179688 -0.109375 3.625 0.164062 2.914062 0.164062 C 2.515625 0.164062 2.183594 0.0703125 1.910156 -0.121094 C 1.746094 -0.234375 1.570312 -0.417969 1.386719 -0.667969 L 1.386719 0 L 0.578125 0 Z M 3.929688 -1.175781 C 4.164062 -1.554688 4.28125 -2.050781 4.28125 -2.671875 C 4.28125 -3.222656 4.164062 -3.675781 3.929688 -4.039062 C 3.691406 -4.398438 3.34375 -4.578125 2.886719 -4.578125 C 2.484375 -4.578125 2.132812 -4.433594 1.832031 -4.136719 C 1.53125 -3.839844 1.382812 -3.351562 1.382812 -2.671875 C 1.382812 -2.179688 1.445312 -1.78125 1.566406 -1.476562 C 1.796875 -0.898438 2.230469 -0.609375 2.859375 -0.609375 C 3.335938 -0.609375 3.691406 -0.800781 3.929688 -1.175781 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-14\">\n",
"<path style=\"stroke:none;\" d=\"M 1.597656 -0.789062 C 1.78125 -0.644531 2 -0.570312 2.257812 -0.570312 C 2.566406 -0.570312 2.863281 -0.644531 3.15625 -0.785156 C 3.644531 -1.023438 3.886719 -1.414062 3.886719 -1.953125 L 3.886719 -2.660156 C 3.78125 -2.59375 3.640625 -2.535156 3.472656 -2.492188 C 3.304688 -2.445312 3.136719 -2.414062 2.972656 -2.390625 L 2.441406 -2.324219 C 2.121094 -2.28125 1.882812 -2.214844 1.722656 -2.125 C 1.453125 -1.972656 1.320312 -1.726562 1.320312 -1.390625 C 1.320312 -1.136719 1.410156 -0.9375 1.597656 -0.789062 Z M 3.445312 -3.167969 C 3.648438 -3.195312 3.785156 -3.28125 3.851562 -3.421875 C 3.890625 -3.5 3.910156 -3.613281 3.910156 -3.757812 C 3.910156 -4.058594 3.804688 -4.277344 3.589844 -4.410156 C 3.378906 -4.546875 3.074219 -4.613281 2.675781 -4.613281 C 2.21875 -4.613281 1.890625 -4.492188 1.699219 -4.242188 C 1.59375 -4.105469 1.523438 -3.902344 1.488281 -3.632812 L 0.667969 -3.632812 C 0.683594 -4.277344 0.894531 -4.726562 1.296875 -4.976562 C 1.699219 -5.230469 2.164062 -5.355469 2.695312 -5.355469 C 3.3125 -5.355469 3.808594 -5.238281 4.195312 -5.003906 C 4.574219 -4.769531 4.765625 -4.40625 4.765625 -3.910156 L 4.765625 -0.898438 C 4.765625 -0.808594 4.785156 -0.734375 4.820312 -0.679688 C 4.859375 -0.625 4.9375 -0.59375 5.058594 -0.59375 C 5.097656 -0.59375 5.140625 -0.597656 5.191406 -0.601562 C 5.238281 -0.609375 5.292969 -0.617188 5.347656 -0.625 L 5.347656 0.0234375 C 5.210938 0.0625 5.105469 0.0859375 5.035156 0.0976562 C 4.960938 0.109375 4.863281 0.113281 4.742188 0.113281 C 4.4375 0.113281 4.21875 0.00390625 4.082031 -0.210938 C 4.011719 -0.324219 3.960938 -0.484375 3.929688 -0.695312 C 3.75 -0.460938 3.496094 -0.253906 3.160156 -0.0820312 C 2.824219 0.0898438 2.453125 0.175781 2.050781 0.175781 C 1.566406 0.175781 1.167969 0.0273438 0.863281 -0.265625 C 0.554688 -0.5625 0.398438 -0.929688 0.398438 -1.371094 C 0.398438 -1.855469 0.550781 -2.234375 0.855469 -2.5 C 1.15625 -2.765625 1.554688 -2.929688 2.046875 -2.992188 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-15\">\n",
"<path style=\"stroke:none;\" d=\"M 1.398438 -2.3125 C 1.421875 -1.90625 1.515625 -1.578125 1.683594 -1.324219 C 2.007812 -0.847656 2.574219 -0.609375 3.390625 -0.609375 C 3.753906 -0.609375 4.085938 -0.664062 4.382812 -0.765625 C 4.964844 -0.96875 5.253906 -1.328125 5.253906 -1.851562 C 5.253906 -2.242188 5.132812 -2.519531 4.886719 -2.6875 C 4.640625 -2.847656 4.253906 -2.988281 3.726562 -3.109375 L 2.753906 -3.328125 C 2.117188 -3.472656 1.671875 -3.632812 1.40625 -3.804688 C 0.949219 -4.101562 0.722656 -4.550781 0.722656 -5.148438 C 0.722656 -5.792969 0.945312 -6.320312 1.390625 -6.734375 C 1.835938 -7.148438 2.46875 -7.351562 3.285156 -7.351562 C 4.039062 -7.351562 4.675781 -7.171875 5.203125 -6.808594 C 5.726562 -6.445312 5.992188 -5.867188 5.992188 -5.070312 L 5.078125 -5.070312 C 5.03125 -5.453125 4.925781 -5.746094 4.765625 -5.953125 C 4.46875 -6.328125 3.964844 -6.515625 3.257812 -6.515625 C 2.683594 -6.515625 2.273438 -6.394531 2.023438 -6.152344 C 1.773438 -5.910156 1.644531 -5.632812 1.644531 -5.3125 C 1.644531 -4.960938 1.792969 -4.703125 2.085938 -4.539062 C 2.277344 -4.4375 2.710938 -4.304688 3.390625 -4.148438 L 4.394531 -3.921875 C 4.878906 -3.8125 5.253906 -3.660156 5.515625 -3.46875 C 5.972656 -3.132812 6.203125 -2.644531 6.203125 -2.007812 C 6.203125 -1.210938 5.914062 -0.644531 5.335938 -0.304688 C 4.757812 0.0390625 4.085938 0.210938 3.320312 0.210938 C 2.429688 0.210938 1.730469 -0.0195312 1.226562 -0.472656 C 0.722656 -0.925781 0.472656 -1.539062 0.484375 -2.3125 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-16\">\n",
"<path style=\"stroke:none;\" d=\"M 1.558594 -1.148438 C 1.796875 -0.769531 2.175781 -0.582031 2.699219 -0.582031 C 3.105469 -0.582031 3.441406 -0.757812 3.703125 -1.105469 C 3.964844 -1.457031 4.097656 -1.957031 4.097656 -2.613281 C 4.097656 -3.273438 3.960938 -3.761719 3.691406 -4.078125 C 3.421875 -4.398438 3.085938 -4.554688 2.691406 -4.554688 C 2.25 -4.554688 1.890625 -4.386719 1.613281 -4.046875 C 1.339844 -3.710938 1.203125 -3.210938 1.203125 -2.554688 C 1.203125 -1.992188 1.320312 -1.523438 1.558594 -1.148438 Z M 3.53125 -5.070312 C 3.6875 -4.972656 3.863281 -4.800781 4.0625 -4.554688 L 4.0625 -7.195312 L 4.90625 -7.195312 L 4.90625 0 L 4.117188 0 L 4.117188 -0.726562 C 3.910156 -0.40625 3.667969 -0.171875 3.390625 -0.03125 C 3.109375 0.113281 2.789062 0.1875 2.425781 0.1875 C 1.84375 0.1875 1.339844 -0.0585938 0.914062 -0.550781 C 0.488281 -1.039062 0.273438 -1.691406 0.273438 -2.503906 C 0.273438 -3.265625 0.46875 -3.925781 0.855469 -4.484375 C 1.246094 -5.042969 1.800781 -5.320312 2.523438 -5.320312 C 2.925781 -5.320312 3.261719 -5.238281 3.53125 -5.070312 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-17\">\n",
"<path style=\"stroke:none;\" d=\"M 0.644531 -5.230469 L 1.480469 -5.230469 L 1.480469 -4.488281 C 1.726562 -4.792969 1.988281 -5.011719 2.265625 -5.148438 C 2.542969 -5.28125 2.851562 -5.347656 3.1875 -5.347656 C 3.929688 -5.347656 4.433594 -5.085938 4.691406 -4.570312 C 4.835938 -4.289062 4.90625 -3.882812 4.90625 -3.355469 L 4.90625 0 L 4.015625 0 L 4.015625 -3.296875 C 4.015625 -3.617188 3.964844 -3.871094 3.871094 -4.066406 C 3.714844 -4.390625 3.433594 -4.554688 3.023438 -4.554688 C 2.8125 -4.554688 2.644531 -4.535156 2.507812 -4.492188 C 2.269531 -4.421875 2.058594 -4.277344 1.875 -4.0625 C 1.726562 -3.890625 1.632812 -3.710938 1.589844 -3.527344 C 1.546875 -3.34375 1.523438 -3.082031 1.523438 -2.738281 L 1.523438 0 L 0.644531 0 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-18\">\n",
"<path style=\"stroke:none;\" d=\"M 0.761719 -7.171875 L 1.734375 -7.171875 L 1.734375 -0.855469 L 5.367188 -0.855469 L 5.367188 0 L 0.761719 0 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-19\">\n",
"<path style=\"stroke:none;\" d=\"M 0.761719 -7.171875 L 1.910156 -7.171875 L 5.53125 -1.363281 L 5.53125 -7.171875 L 6.453125 -7.171875 L 6.453125 0 L 5.367188 0 L 1.6875 -5.804688 L 1.6875 0 L 0.761719 0 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-20\">\n",
"<path style=\"stroke:none;\" d=\"M 1.050781 -5.230469 L 2.054688 -1.109375 L 3.078125 -5.230469 L 4.0625 -5.230469 L 5.085938 -1.132812 L 6.15625 -5.230469 L 7.035156 -5.230469 L 5.515625 0 L 4.605469 0 L 3.539062 -4.046875 L 2.507812 0 L 1.597656 0 L 0.0859375 -5.230469 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-21\">\n",
"<path style=\"stroke:none;\" d=\"M 0.203125 -7.171875 L 1.335938 -7.171875 L 3.398438 -3.726562 L 5.460938 -7.171875 L 6.597656 -7.171875 L 3.886719 -2.890625 L 3.886719 0 L 2.914062 0 L 2.914062 -2.890625 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-22\">\n",
"<path style=\"stroke:none;\" d=\"M 0.667969 -5.230469 L 1.503906 -5.230469 L 1.503906 -4.328125 C 1.570312 -4.503906 1.738281 -4.714844 2.007812 -4.96875 C 2.273438 -5.21875 2.582031 -5.347656 2.929688 -5.347656 C 2.945312 -5.347656 2.972656 -5.34375 3.011719 -5.34375 C 3.050781 -5.339844 3.117188 -5.332031 3.210938 -5.320312 L 3.210938 -4.394531 C 3.160156 -4.40625 3.113281 -4.410156 3.070312 -4.414062 C 3.023438 -4.417969 2.976562 -4.417969 2.925781 -4.417969 C 2.484375 -4.417969 2.140625 -4.277344 1.90625 -3.992188 C 1.667969 -3.707031 1.546875 -3.378906 1.546875 -3.007812 L 1.546875 0 L 0.667969 0 Z \"/>\n",
"</symbol>\n",
"<symbol overflow=\"visible\" id=\"glyph1-23\">\n",
"<path style=\"stroke:none;\" d=\"M 0.625 -7.171875 L 1.46875 -7.171875 L 1.46875 -3.007812 L 3.726562 -5.230469 L 4.847656 -5.230469 L 2.847656 -3.273438 L 4.960938 0 L 3.835938 0 L 2.207031 -2.636719 L 1.46875 -1.960938 L 1.46875 0 L 0.625 0 Z \"/>\n",
"</symbol>\n",
"</g>\n",
"</defs>\n",
"<g id=\"surface49\">\n",
"<rect x=\"0\" y=\"0\" width=\"450\" height=\"300\" style=\"fill:rgb(100%,100%,100%);fill-opacity:1;stroke:none;\"/>\n",
"<g style=\"fill:rgb(0%,0%,0%);fill-opacity:1;\">\n",
" <use xlink:href=\"#glyph0-1\" x=\"156.476562\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-2\" x=\"167.309082\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-3\" x=\"175.651367\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-4\" x=\"179.818848\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-5\" x=\"188.161133\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-6\" x=\"193.15625\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-7\" x=\"197.32373\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-2\" x=\"205.666016\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-8\" x=\"214.008301\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-9\" x=\"218.175781\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-10\" x=\"228.180664\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-11\" x=\"237.343262\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-12\" x=\"246.505859\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-3\" x=\"255.668457\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-4\" x=\"259.835938\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-5\" x=\"268.178223\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-6\" x=\"273.17334\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-10\" x=\"277.34082\" y=\"16.550781\"/>\n",
" <use xlink:href=\"#glyph0-13\" x=\"286.503418\" y=\"16.550781\"/>\n",
"</g>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,0%,100%);fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke:rgb(100%,100%,100%);stroke-opacity:0.1;stroke-miterlimit:10;\" d=\"M 290 130 C 290 159.304688 272.933594 185.925781 246.304688 198.15625 C 219.675781 210.386719 188.359375 205.988281 166.128906 186.894531 L 215 130 Z \" transform=\"matrix(1,0,0,1,10,30)\"/>\n",
"<path style=\"fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 248.390625 202.699219 L 254.652344 216.328125 L 310.472656 216.328125 \" transform=\"matrix(1,0,0,1,10,30)\"/>\n",
"<g style=\"fill:rgb(0%,0%,0%);fill-opacity:1;\">\n",
" <use xlink:href=\"#glyph1-1\" x=\"269.652344\" y=\"244.03125\"/>\n",
" <use xlink:href=\"#glyph1-2\" x=\"277.982422\" y=\"244.03125\"/>\n",
" <use xlink:href=\"#glyph1-3\" x=\"283.543945\" y=\"244.03125\"/>\n",
" <use xlink:href=\"#glyph1-4\" x=\"288.543945\" y=\"244.03125\"/>\n",
" <use xlink:href=\"#glyph1-5\" x=\"290.765625\" y=\"244.03125\"/>\n",
" <use xlink:href=\"#glyph1-6\" x=\"295.765625\" y=\"244.03125\"/>\n",
" <use xlink:href=\"#glyph1-7\" x=\"301.327148\" y=\"244.03125\"/>\n",
" <use xlink:href=\"#glyph1-8\" x=\"304.105469\" y=\"244.03125\"/>\n",
" <use xlink:href=\"#glyph1-4\" x=\"311.327148\" y=\"244.03125\"/>\n",
" <use xlink:href=\"#glyph1-9\" x=\"313.548828\" y=\"244.03125\"/>\n",
" <use xlink:href=\"#glyph1-10\" x=\"316.327148\" y=\"244.03125\"/>\n",
"</g>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(100%,0%,0%);fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke:rgb(100%,100%,100%);stroke-opacity:0.1;stroke-miterlimit:10;\" d=\"M 156.175781 187.839844 C 125.609375 161.585938 121.25 115.867188 146.308594 84.3125 L 205.046875 130.949219 Z \" transform=\"matrix(1,0,0,1,10,30)\"/>\n",
"<path style=\"fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 125.40625 138.539062 L 110.472656 139.960938 L 71.328125 139.960938 \" transform=\"matrix(1,0,0,1,10,30)\"/>\n",
"<g style=\"fill:rgb(0%,0%,0%);fill-opacity:1;\">\n",
" <use xlink:href=\"#glyph1-1\" x=\"81.328125\" y=\"167.664062\"/>\n",
" <use xlink:href=\"#glyph1-11\" x=\"89.658203\" y=\"167.664062\"/>\n",
" <use xlink:href=\"#glyph1-12\" x=\"95.219727\" y=\"167.664062\"/>\n",
" <use xlink:href=\"#glyph1-13\" x=\"103.549805\" y=\"167.664062\"/>\n",
" <use xlink:href=\"#glyph1-14\" x=\"109.111328\" y=\"167.664062\"/>\n",
" <use xlink:href=\"#glyph1-4\" x=\"114.672852\" y=\"167.664062\"/>\n",
"</g>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,50.196078%,0%);fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke:rgb(100%,100%,100%);stroke-opacity:0.1;stroke-miterlimit:10;\" d=\"M 156.261719 83.363281 C 164.246094 73.308594 174.675781 65.472656 186.554688 60.601562 L 215 130 Z \" transform=\"matrix(1,0,0,1,10,30)\"/>\n",
"<path style=\"fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 166.945312 66.039062 L 157.933594 54.046875 L 120.167969 54.046875 \" transform=\"matrix(1,0,0,1,10,30)\"/>\n",
"<g style=\"fill:rgb(0%,0%,0%);fill-opacity:1;\">\n",
" <use xlink:href=\"#glyph1-15\" x=\"130.167969\" y=\"81.75\"/>\n",
" <use xlink:href=\"#glyph1-10\" x=\"136.837891\" y=\"81.75\"/>\n",
" <use xlink:href=\"#glyph1-16\" x=\"141.837891\" y=\"81.75\"/>\n",
" <use xlink:href=\"#glyph1-17\" x=\"147.399414\" y=\"81.75\"/>\n",
" <use xlink:href=\"#glyph1-2\" x=\"152.960938\" y=\"81.75\"/>\n",
" <use xlink:href=\"#glyph1-10\" x=\"158.522461\" y=\"81.75\"/>\n",
"</g>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(100%,100%,0%);fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke:rgb(100%,100%,100%);stroke-opacity:0.1;stroke-miterlimit:10;\" d=\"M 186.554688 60.601562 C 209.832031 51.0625 236.34375 53.828125 257.152344 67.964844 L 215 130 Z \" transform=\"matrix(1,0,0,1,10,30)\"/>\n",
"<path style=\"fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 223.300781 50.433594 L 224.855469 35.511719 L 261.808594 35.511719 \" transform=\"matrix(1,0,0,1,10,30)\"/>\n",
"<g style=\"fill:rgb(0%,0%,0%);fill-opacity:1;\">\n",
" <use xlink:href=\"#glyph1-18\" x=\"239.855469\" y=\"63.210938\"/>\n",
" <use xlink:href=\"#glyph1-6\" x=\"245.416992\" y=\"63.210938\"/>\n",
" <use xlink:href=\"#glyph1-17\" x=\"250.978516\" y=\"63.210938\"/>\n",
" <use xlink:href=\"#glyph1-16\" x=\"256.540039\" y=\"63.210938\"/>\n",
" <use xlink:href=\"#glyph1-6\" x=\"262.101562\" y=\"63.210938\"/>\n",
" <use xlink:href=\"#glyph1-17\" x=\"267.663086\" y=\"63.210938\"/>\n",
"</g>\n",
"<path style=\"fill-rule:nonzero;fill:rgb(0%,100%,100%);fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:bevel;stroke:rgb(100%,100%,100%);stroke-opacity:0.1;stroke-miterlimit:10;\" d=\"M 279.246094 56.265625 C 299.792969 70.230469 312.09375 93.460938 312.09375 118.300781 L 237.09375 118.300781 Z \" transform=\"matrix(1,0,0,1,10,30)\"/>\n",
"<path style=\"fill:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke:rgb(0%,0%,0%);stroke-opacity:1;stroke-miterlimit:10;\" d=\"M 307.792969 80.863281 L 321.050781 73.84375 L 368.59375 73.84375 \" transform=\"matrix(1,0,0,1,10,30)\"/>\n",
"<g style=\"fill:rgb(0%,0%,0%);fill-opacity:1;\">\n",
" <use xlink:href=\"#glyph1-19\" x=\"336.050781\" y=\"101.546875\"/>\n",
" <use xlink:href=\"#glyph1-2\" x=\"343.272461\" y=\"101.546875\"/>\n",
" <use xlink:href=\"#glyph1-20\" x=\"348.833984\" y=\"101.546875\"/>\n",
" <use xlink:href=\"#glyph1-7\" x=\"356.055664\" y=\"101.546875\"/>\n",
" <use xlink:href=\"#glyph1-21\" x=\"358.833984\" y=\"101.546875\"/>\n",
" <use xlink:href=\"#glyph1-6\" x=\"365.503906\" y=\"101.546875\"/>\n",
" <use xlink:href=\"#glyph1-22\" x=\"371.06543\" y=\"101.546875\"/>\n",
" <use xlink:href=\"#glyph1-23\" x=\"374.395508\" y=\"101.546875\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
]
2013-12-30 17:18:10 -05:00
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 22
2014-01-09 13:34:00 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"By default, both `ihaskell-diagrams` and `ihaskell-chart` use SVG displays. However, the notebook does not support interactive resizing for SVG image. However, if you use `:set no-svg`, all SVG outputs will instead be shown as PNG images, and they can be resized easily."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
":set no-svg\n",
"\n",
"toRenderable \n",
" $ pie_title .~ \"Relative Population\"\n",
" $ pie_plot . pie_data .~ map pitem values\n",
" $ def"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"png": "iVBORw0KGgoAAAANSUhEUgAAAcIAAAEsCAIAAADfNCTgAAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nO3deVwU9f8H8NeyyyGg6CooivKTwyNSzLJUMLxQUVHDAxME0RTvAzUjNbW8K0tDLSVTv3lh5hHeiuaJeJUBWoIcCggoisACC+z8/pgigl1YmN2dneX9fPSH7nzmM+81fDnHZz4fEcMwIIQQUldGfBdACCHCRjFKCCGcUIwSQggnFKOEEMIJxSghhHAi4bsAohX+/v5//vln+W+NjY2dnJxGjRo1bNiwGvft3r17WVnZiRMnrK2tVbXJyMiQyWQtWrSwsLAA4OzszDDMpUuXWrZsqdnKbWxsevbsOWfOHEtLS449q8Lv9yWGgCGG6I033lD6v3vHjh017iuRSACkpaVV06Z///4AIiIi2N+ynaekpGipcjc3N4VCwb1zpfj9vsQA0EW9Ifvoo4+uX79+/fr1w4cPOzk5AVi3bp02DnTr1q1bt261aNFCUx3OnTv3+vXrUVFR06ZNA3D16tXLly9rqnPuNP59ibDxneNEK9hzum3btpV/sn37dgAmJibsad2LFy+mT5/evn17e3t7Hx+f+/fvl7eseHaWnJw8duzY9u3bt2vXzt/f//DhwwzDzJw5k73+ffvttzdt2sQwTO/evT08PJ4+ffrJJ594eHh89tlnbFfx8fEeHh4DBgwoLi6u/qCVKv/666/Z35aVlbFp9d133zEMU1pa+tlnn3Xu3NnCwqJDhw7z5s2TyWRszx4eHsOHD//11199fHwcHR39/PzKTzDZrR4eHgUFBewn5QVz/L7VlMQW369fv379+kVHR/v4+Dg5OQUHB9+5c0cT/4eJHqEYNUxVYzQgIACAm5sbwzAlJSWdO3cG0LRpU2dnZwBNmjSJjY1lW1aMFQcHBwBt27Z1c3MzMjISiUTXrl3z9/dv3LgxgI4dO65evZqpcJG7b98+AC1btmS7WrVqFYBRo0bVeNBKlZfHaG5uboMGDQDs2bOHYRg/Pz/2WJ07dzYyMgLg7u6uUCiysrIAmJqampubS6VStk3btm0LCwsZhmG3Anj16hXbrUgkApCcnMzx+1ZTEsMwZWVl7KamTZu+/vrrYrEYQPPmzdl/VIjBoBg1TGwY2djYODs7Ozs7syng4uLy8OFDhmF2794NoH379kVFRQzDBAUFAZgyZQq7b3msJCYm9u7d28/Pj/28R48eAL766itG9b1CmUzWqFEjAOw5F7vLL7/8UuNBK1Xu7u4+ffr0iRMn2tvbs/mYmJh4584d9kA3btxgGObhw4dswh4+fLg8KNnyLly4wJYRHh7OqB2jdfi+1ZTEVIjRb775hmGY2NhY9rfx8fEa/v9NeEX3Rg1ZWVmZXC4vKirKzc0FIJfL2b/Yv/32GwCFQhEQEODr68s+GY+Kiqq0u4ODw969ez08PPz9/bt06XL9+nW2k2qO2KBBgzFjxgA4ceJEdnb2jRs3bGxsBg0apP5BWVeuXNmyZcuOHTtSUlJsbW1/+OEHBwcHtoBOnTq9/fbbAJycnDw8PABcu3aN3UskEgUHBwPo3bt3nz59AMTFxan/x1WH71tjSSxvb28ALi4u7L9n+fn56ldF9B8NeDJka9asmTx5MoCcnBw3N7cHDx5s27btyy+/ZP8ai8VihUIBoGXLlqNGjSq/Fi6XmJjYo0eP7OxsNze3IUOGNG3aVFXqVRQQEBAeHn78+HE7OzuFQuHn58ee7ql5UNa8efN8fX2NjIxsbGzs7OzYy2GZTAaATSIW+2v2cwDm5ubsySAAKysrAOyxyjEMA6CkpIRRNiNPHb5vjSWx2FNjAOxVPzEwFKP1glQq7d+//4MHD+Lj4wG0b98egEQiiYiIEIlEycnJsbGxVUdNHjx4MDs7e8iQIZGRkQzDdOzYUZ1jubu7Ozg43Lhxw9TUFEBgYCD7uZoHZdnb27/zzjuVPuzUqROA6Ojo3NxcKyursrKy8+fPl38OoKCg4M6dO127di0pKWE3seMTpFKpqalpcXFxWlpao0aNbt++rfSgdfi+NZZE6gP6t7G+aNKkCf45S/L19WUf7/j5+S1ZssTNzc3b27vq9S/7IOjhw4cHDx6cPn06exnOnt+Zm5sDCA8PP3HiRKW9RCLR+PHjFQrFxYsXXV1dXV1d2c/VPGg1BgwYwEZkx44d58yZ065du+zs7FatWo0fP768zZAhQ4KDg52cnNLS0qysrN5//30AYrH4tddeA9C7d+/g4OCRI0ey90a5f191SiKGj99bs0RLVA14atSoUVZWFsMwly9f7tChA/szIJFIli1bVlZWxrYsf+RSUlLSr18/NnHc3NzYIZxeXl4Mwxw6dIi9fA4ICGCqDEdPTExkP9mwYUPFqqo5aKXKy5/UV/L48eN33323/Kf39ddfj4uLY/55iCSRSEJDQ83MzADY2NicO3eufMdr166xZ77Gxsaffvpp8+bNUeURU92+r6qSmAqPmHJycthP2JsYMTExtf9fSvSXiKFpm+srhULx6NGj3Nzcjh07smdbSqWlpYlEoqpvPZaWlj5//tzc3Lxhw4YaP2j1MjMzExIS2rRp07p1a/aT7OxsGxsbiURSUlIik8lSU1OdnZ3ZO6oVpaSkNG3atPr3Suv2fauWROoPilFiCCrGKN+1kHqH7o0SQggn9KSeGAKpVPrw4UOlD44I0Ta6qCeEEE7oop4QQjihGCWEEE4oRgkhhBOKUUII4YRilBBCOKEYJYQQTihGCSGEE4pRQgjhhGKUEEI4oRglhBBOKEYJIYQTilFCCOGEYpQQQjihGCWEEE4oRgkhhBOKUUII4YRilBBCOKEYJYQQTihGCSGEE4pRQgjhhGKUEEI4oRglhBBOKEYJIYQTilFCCOGEYpQQQjihGCWEEE4oRgkhhBOKUUII4YRilBBCOKEYJYQQTihGCSGEE4pRQgjhhGKUEEI4oRglBkUmkyUnJ9d59/j4eM3VQuoLilFiUO7cuTN58uQ67+7j46PBYkg9QTFKDJlCoQgJCbG3t/f19Y2LiwNw/PjxxYsX9+7du23btj/99BPbZt68ec7OznPmzGEYRp1dCKmIYpQYspiYmLi4uLt374aGhi5duhRAbm7u/v379+3bt3Xr1i+++ALA+fPn//jjjytXrrRs2TI3N1edXQipiGKUGLJTp05NmDBBKpV26dIlKSmpoKAAwLBhw2xtbQcOHPjkyRMA58+fDwgIaN68eXBwsFgsVmcXQiqiGCWGLDU11dramv11SUkJwzAAzM3NAYhEIvbz9PT05s2bs58bGxurswshFVGMEkPm6ekZFRUFICkpSSqVWlpaVm0zcODAc+fOAbh27VpRUZE6uxBSEcUoMTSXLl1q8Y/8/Py4uLh+/fp169Zt7ty5StsPHjz43r17vXr1WrFihbW1tZeXV427EFKRiL1mIcSAZWRkWFlZsRfmqqSnp9va2pZftquzCyEsilFCCOGELuoJIYQTilEiYCUlJcbGxiIdonGjpCoJ3wUQUndJSUlt27b966+/+C6E1Gt0NkoE7OHDh05OTnxXQeo7ilEiYAkJCc7OznxXQeo7ilEiYHQ2SvQBxSgRsISEBIpRwjuKUSJgDx8+pIt6wjsafk+ESi6XW1lZ5eXlSSQ04ITwic5G9UhaWtq5c+dkMlmNLWmtCwBJSUmtW7emDCW8oxjVCwqFIjAw8Pvvv4+NjZ0yZUp4eHj17WmtC9CNUaI3KEb1QnJy8o0bNz7++OO5c+fu3r27RYsWAAICAu7duwcgNjY2KCio0loXSle2+Pzzzx0dHXv27BkbG1u1B/6+n1bQjVGiJyhG9YKDg0Pnzp1bt249derUkydPDhkyBICLi8uxY8cAHD161MXFpdJaF1VXtkhMTDxy5EhMTMy8efPGjRtXtQdev6Lm0dko0RMUo/oiIiIiMjKyRYsWs2fPHj9+PAAfH5/jx48DOH78+HvvvVdprQtUWdkiMjLS0dHx1KlTcrk8KyvrxYsXlXrg9ftpHg0aJXqCbs/rhWvXrhUXF/fp0+fNN99cvHixg4NDdna2
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 23
2014-01-09 13:34:00 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, the `ihaskell-magic` chart uses the [magic](http://hackage.haskell.org/package/magic) library (bindings to `libmagic`) to create a display mechanism for `ByteString`s. If you try to load an image, for instance, you will see that image immediately in the notebook."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import qualified Data.ByteString as B\n",
2014-01-09 14:58:34 -05:00
"B.readFile \"code/IHaskell/images/ihaskell-notebook.png\""
2014-01-09 13:34:00 -05:00
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
2014-01-09 14:58:34 -05:00
"png": "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
2014-01-09 13:34:00 -05:00
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 25
2014-01-09 13:34:00 -05:00
},
{
2014-01-09 14:58:34 -05:00
"cell_type": "markdown",
2014-01-09 13:34:00 -05:00
"metadata": {},
2014-01-09 14:58:34 -05:00
"source": [
"In addition to displaying outputs in a rich format, IHaskell has a bunch of useful features.\n",
"\n",
"For instance, the popular linting tool `hlint` is integrated and turned on by default. Let's write some ugly code, and see what it tells us:"
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- There is also hlint integration enabled by default.\n",
"-- If you write sketchy code, it will tell you:\n",
"f :: Int -> Int\n",
"f x = x + 1\n",
"\n",
"-- Most warnings are orange...\n",
"f $ 3\n",
"\n",
"-- But more severe warnings are red.\n",
"putStrLn (show 3)\n",
"do\n",
" return 3"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
2014-01-09 12:39:50 -05:00
" <div class=\"suggestion-name\" style=\"clear:both;\"> Redundant $</div> <div class=\"suggestion-row\" style=\"float: left;\"> <div class=\"suggestion-warning\">Found:</div> <div class=\"highlight-code\" id=\"haskell\"> f $ 3\n",
"</div> </div> <div class=\"suggestion-row\" style=\"float: left;\"> <div class=\"suggestion-warning\">Why Not:</div> <div class=\"highlight-code\" id=\"haskell\"> f 3\n",
"</div> </div> <div class=\"suggestion-name\" style=\"clear:both;\"> Use print</div> <div class=\"suggestion-row\" style=\"float: left;\"> <div class=\"suggestion-error\">Found:</div> <div class=\"highlight-code\" id=\"haskell\"> putStrLn (show 3)\n",
"</div> </div> <div class=\"suggestion-row\" style=\"float: left;\"> <div class=\"suggestion-error\">Why Not:</div> <div class=\"highlight-code\" id=\"haskell\"> print 3\n",
"</div> </div> <div class=\"suggestion-name\" style=\"clear:both;\"> Redundant do</div> <div class=\"suggestion-row\" style=\"float: left;\"> <div class=\"suggestion-error\">Found:</div> <div class=\"highlight-code\" id=\"haskell\">return 3\n",
"</div> </div> <div class=\"suggestion-row\" style=\"float: left;\"> <div class=\"suggestion-error\">Why Not:</div> <div class=\"highlight-code\" id=\"haskell\"> return 3\n",
"</div> </div> "
2013-12-30 17:18:10 -05:00
],
"metadata": {},
"output_type": "display_data",
"text": [
2014-01-09 12:39:50 -05:00
"Line 7: Redundant $\n",
2013-12-30 17:18:10 -05:00
"Found:\n",
" f $ 3\n",
"\n",
"Why not:\n",
" f 3\n",
2014-01-09 12:39:50 -05:00
"Line 10: Use print\n",
2013-12-30 17:18:10 -05:00
"Found:\n",
" putStrLn (show 3)\n",
"\n",
"Why not:\n",
" print 3\n",
2014-01-09 12:39:50 -05:00
"Line 11: Redundant do\n",
2013-12-30 17:18:10 -05:00
"Found:\n",
2014-01-09 12:39:50 -05:00
"return 3\n",
2013-12-30 17:18:10 -05:00
"\n",
"Why not:\n",
" return 3"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"4"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"3"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"3"
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 26
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you're an experienced Haskeller, though, and don't want `hlint` telling you what to do, you can easily turn it off:"
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- If hlint annoys you, though, you can turn it off.\n",
"-- Note that this only takes effect in the next cell execution.\n",
2014-01-09 12:39:50 -05:00
":set no-lint"
2013-12-30 17:18:10 -05:00
],
"language": "python",
"metadata": {},
"outputs": [],
2014-01-09 14:58:34 -05:00
"prompt_number": 27
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
2014-01-09 12:39:50 -05:00
"-- You could similarly use `:set lint` to turn it back on.\n",
2013-12-30 17:18:10 -05:00
"f $ 3"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"text": [
"4"
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 28
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In addition to `hlint` integration, IHaskell also integrates **Hoogle** for documentation searches. IHaskell provides two directives for searching Hoogle. The first of these, `:document` (or shorthands), looks for exact matches."
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
":doc filterM"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data"
}
],
"prompt_number": 35
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2014-01-09 15:02:57 -05:00
"Like with `:info`, the Hoogle directives use the IPython documentation pager to show you their output. You can press Escape to dismiss the pager. If you're reading this in it's HTML form, the output looks like this:\n",
"\n",
""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The other provided command is `:hoogle`. This does a normal Hoogle search, and thus lets you use imperfect matching and searching by type signature."
2014-01-09 14:58:34 -05:00
]
},
2014-01-09 15:02:57 -05:00
{
"cell_type": "code",
"collapsed": false,
2014-01-09 15:04:15 -05:00
"input": [
":hoogle :: [a] -> [(a, b)]"
],
2014-01-09 15:02:57 -05:00
"language": "python",
"metadata": {},
2014-01-09 15:04:15 -05:00
"outputs": [
{
"metadata": {},
"output_type": "display_data"
}
],
"prompt_number": 36
2014-01-09 15:02:57 -05:00
},
2014-01-09 15:04:59 -05:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The pager will show you documentation for things that could have that type signature or a similar one. It automatically formats inline Haskell code and hyperlinks the identifiers to their respective Haddock documentations:\n",
"\n",
""
]
},
2014-01-09 14:58:34 -05:00
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All of the code you normally put into IHaskell is (like in GHCi) interpreted. However, sometimes you've perfected a function, and now need it to run faster. In that case, you can go ahead and define a module in a single cell. As long as your module has a module header along the lines of `module Name where`, IHaskell will recognize it as a module. It will create the file `A/B.hs`, compile it, and load it. "
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- If your code isn't running fast enough, you can just put it into a module.\n",
"module A.B where\n",
"\n",
"fib 0 = 1\n",
"fib 1 = 1\n",
"fib n = fib (n-1) + fib (n-2)"
],
"language": "python",
"metadata": {},
"outputs": [],
2014-01-09 14:58:34 -05:00
"prompt_number": 29
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that the module is by default imported unqualified, as though you had typed `import A.B`."
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"-- The module is automatically imported unqualified.\n",
"print $ A.B.fib 20\n",
"print $ fib 20"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"text": [
"10946"
]
},
{
"metadata": {},
"output_type": "display_data",
"text": [
"10946"
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 32
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that since a new module is imported, all previous bound identifiers are now unbound. For instance, we no longer have access to the `f` function from before:"
]
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"f 3"
],
"language": "python",
"metadata": {},
"outputs": [
{
"html": [
"<span class='err-msg'>Not in scope: `f'</span>"
],
"metadata": {},
"output_type": "display_data",
"text": [
"Not in scope: `f'"
]
}
],
"prompt_number": 33
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"However, if you re-import this module with another import statement, the original implicit import goes away."
]
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "code",
"collapsed": false,
"input": [
"import qualified A.B as Fib\n",
"\n",
"Fib.fib 20\n",
"fib 20"
],
"language": "python",
"metadata": {},
"outputs": [
{
"metadata": {},
"output_type": "display_data",
"text": [
"10946"
]
},
{
"html": [
2014-01-09 12:39:50 -05:00
"<span class='err-msg'>Not in scope: `fib'<br/>Perhaps you meant `Fib.fib' (imported from A.B)</span>"
2013-12-30 17:18:10 -05:00
],
"metadata": {},
"output_type": "display_data",
"text": [
"Not in scope: `fib'\n",
"Perhaps you meant `Fib.fib' (imported from A.B)"
]
}
],
2014-01-09 14:58:34 -05:00
"prompt_number": 34
2013-12-30 17:18:10 -05:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Thanks!\n",
"---\n",
"\n",
"I hope you've enjoyed this little demo of **IHaskell**!\n",
"\n",
"All of this is running using [IPython notebook][http://ipython.org], communicating asynchronously with a language evaluator kernel written in pure Haskell. \n",
"\n",
"In addition to code cells, you can also type Markdown, and have it be displayed as HTML - just like I'm doing with this cell.\n",
"\n",
"I hope you find IHaskell useful, and please report any bugs or features requests [on Github](https://github.com/gibiansky/IHaskell/issues). If you have any comments, want to contribute, or just want to get in touch, don't hesitate to contact me at Andrew dot Gibiansky at Gmail."
]
}
],
"metadata": {}
}
]
}