Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first checking

  • Loading branch information...
commit fe5ef0be2c67e2242ead7c61cc305bb185af3fd4 0 parents
@mzero authored
7 Makefile
@@ -0,0 +1,7 @@
+all: slides.html
+
+slides.html: slides.md
+ pandoc --offline -s -t slidy -i -o $@ $<
+
+clean:
+ -rm -f slides.html
104 Part1.hs
@@ -0,0 +1,104 @@
+{- To explore this file:
+
+Run ghci from the shell:
+
+ & ghci
+ GHCi, version 7.0.2: http://www.haskell.org/ghc/ :? for help
+ Loading package ghc-prim ... linking ... done.
+ Loading package integer-gmp ... linking ... done.
+ Loading package base ... linking ... done.
+ Loading package ffi-1.0 ... linking ... done.
+ Prelude>
+
+Load up this file:
+
+ Prelude> :load Part1.hs
+ [1 of 1] Compiling Part1 ( Part1.hs, interpreted )
+ Ok, modules loaded: Part1.
+ *Part1>
+
+Try stuff:
+ *Part1> 2 + 2
+ 4
+
+ *Part1> putStr $ poem
+ occasional clouds
+ one gets a rest
+ from moon-viewing
+
+ *Part1> main
+ from moon-viewing
+ occasional clouds
+ one gets a rest
+
+-}
+
+module Part1 where
+
+import Data.Char (toUpper)
+import Data.List (sort)
+
+main = readFile "poem" >>= putStr . process
+
+process t = unlines (sort (lines t))
+
+process' t = (unlines . sort . lines) t
+process'' = unlines . sort . lines
+
+
+poem = "breakfast apple pie\n\
+ \lunch banana yoghurt for\n\
+ \dinner cantaloupe\n"
+
+ -- show the poem in ghci with:
+ -- > putStr $ poem
+
+sortLines = unlines . sort . lines
+reverseLines = unlines . reverse . lines
+firstTwoLines = unlines . take 2 . lines
+
+ -- try applying these to the poem in ghci:
+ -- > putStr $ sortLines poem
+ -- > putStr $ reverseLines poem
+
+byLines f = unlines . f . lines
+
+sortLines' = byLines sort
+reverseLines' = byLines reverse
+firstTwoLines' = byLines (take 2)
+
+
+indent :: String -> String
+indent s = " " ++ s
+
+-- This is commented out, because it won't compile:
+-- indentLines = byLines indent
+
+indentEachLine :: String -> String
+indentEachLine = byLines (map indent)
+
+eachLine :: (String -> String) -> String -> String
+eachLine f = unlines . map f . lines
+
+indentEachLine' :: String -> String
+indentEachLine' = eachLine indent
+
+
+yell :: String -> String
+yell s = map toUpper s ++ "!!!"
+
+yellEachLine :: String -> String
+yellEachLine = eachLine yell
+
+
+eachWord :: (String -> String) -> String -> String
+eachWord f = unwords . map f . words
+
+yellEachWord :: String -> String
+yellEachWord = eachWord yell
+
+eachWordOnEachLine :: (String -> String) -> String -> String
+eachWordOnEachLine f = eachLine (eachWord f)
+
+yellEachWordOnEachLine :: String -> String
+yellEachWordOnEachLine = eachWordOnEachLine yell
30 Part2a.hs
@@ -0,0 +1,30 @@
+module Part2a where
+
+data List α = Nil
+ | Cons α (List α)
+ deriving Show -- makes printing out results possible
+
+empty = Nil
+oneWord = Cons "apple" Nil
+twoWords = Cons "banana" (Cons "cantaloupe" Nil)
+
+mystery1 = Cons "pear" empty
+mystery2 = Cons "peach" oneWord
+mystery3 = Cons "pineapple" mystery3
+-- mystery4 = Cons 42 (Cons "apple" Nil) -- won't compile
+
+dropOne :: List a -> List a
+dropOne (Cons first rest) = rest
+dropOne Nil = Nil
+
+justOne :: List a -> List a
+justOne (Cons a _) = Cons a Nil
+justOne Nil = Nil
+
+firstOne :: List a -> a
+firstOne (Cons a _) = a
+firstOne Nil = error "O Noes!"
+
+maybeFirstOne :: a -> List a -> a
+maybeFirstOne def (Cons first rest) = first
+maybeFirstOne def Nil = def
29 Part2b.hs
@@ -0,0 +1,29 @@
+module Part2b where
+
+-- data [a] = [] | a : [a] -- already built in
+-- infixr 5 : -- already built in
+
+empty = []
+oneWord = "apple" : []
+twoWords = "banana" : "cantaloupe" : []
+
+mystery1 = "pear" : empty
+mystery2 = "peach" : oneWord
+mystery3 = "pineapple" : mystery3
+-- mystery4 = 42 : "apple" : [] -- won't compile
+
+dropOne :: [a] -> [a]
+dropOne (first:rest) = rest
+dropOne [] = []
+
+justOne :: [a] -> [a]
+justOne (a:_) = a:[]
+justOne [] = []
+
+firstOne :: [a] -> a
+firstOne (a:_) = a
+firstOne [] = error "O Noes!"
+
+maybeFirstOne :: a -> [a] -> a
+maybeFirstOne def (first:rest) = first
+maybeFirstOne def [] = def
33 Part2c.hs
@@ -0,0 +1,33 @@
+module Part2c where
+
+-- data [a] = [] | a : [a] -- already built in
+-- infixr 5 : -- already built in
+
+empty = []
+oneWord = ["apple"] -- syntatic sugar
+twoWords = ["banana", "cantaloupe"] -- two teaspoons full
+
+mystery1 = "pear" : empty
+mystery2 = "peach" : oneWord
+mystery3 = "pineapple" : mystery3
+-- mystery4 = [42, "apple"] -- sweet, but still won't compile
+
+dropOne :: [a] -> [a]
+dropOne (first:rest) = rest
+dropOne [] = []
+
+justOne :: [a] -> [a] -- don't confuse these "[a]"s
+justOne (a:_) = [a] -- with this "[a]"
+justOne [] = []
+
+firstOne :: [a] -> a -- normally called 'head'
+firstOne (a:_) = a
+firstOne [] = error "O Noes!"
+
+maybeFirstOne :: a -> [a] -> a
+maybeFirstOne def (first:rest) = first
+maybeFirstOne def [] = def
+
+firstOne' :: [a] -> Maybe a
+firstOne' (a:_) = Just a
+firstOne' [] = Nothing
24 Part2d.hs
@@ -0,0 +1,24 @@
+module Part2d where
+
+
+findAfterStar :: String -> Maybe Char
+findAfterStar (c:d:r) =
+ if c == '*' then Just d
+ else findAfterStar (d:r)
+findAfterStar _ = Nothing
+
+
+
+findAfterChar :: Char -> String -> Maybe Char
+findAfterChar m (c:d:r) =
+ if c == m then Just d
+ else findAfterChar m (d:r)
+findAfterChar _ _ = Nothing
+
+
+
+findAfterElem :: Eq a => a -> [a] -> Maybe a
+findAfterElem m (c:d:r) =
+ if c == m then Just d
+ else findAfterElem m (d:r)
+findAfterElem _ _ = Nothing
25 Part3.hs
@@ -0,0 +1,25 @@
+module Part3 where
+
+runLengthEncode :: Eq a => [a] -> [(a, Int)]
+runLengthEncode [] = []
+runLengthEncode (x:xs) = nextGroup x 1 xs
+ where
+ nextGroup e n [] = [(e, n)]
+ nextGroup e n (y:ys)
+ | e == y = nextGroup e (n + 1) ys
+ | otherwise = (e, n) : nextGroup y 1 ys
+
+
+rlePropLengthPreserved :: [Int] -> Bool
+rlePropLengthPreserved as = length as == (sum $ map snd $ runLengthEncode as)
+
+rlePropDupesCollapsed :: Int -> Bool
+rlePropDupesCollapsed n
+ | m == 0 = runLengthEncode "" == []
+ | otherwise = runLengthEncode (replicate m 'x') == [('x', m)]
+ where m = n `mod` 100
+
+rlePropRoundTrip :: [Int] -> Bool
+rlePropRoundTrip ns = runLengthEncode xs == is
+ where is = zip ['a'..] $ map (\n -> n `mod` 100 + 1) ns
+ xs = concatMap (\(i,n) -> replicate n i) is
3  poem
@@ -0,0 +1,3 @@
+occasional clouds
+one gets a rest
+from moon-viewing
24 rle.cpp
@@ -0,0 +1,24 @@
+#include <list>
+#include <utility>
+using namespace std;
+
+template<typename T>
+list<pair<T,int> > runLengthEncode(const list<T>& as) {
+ list<pair<T, int> > runs;
+ if (!empty(as)) {
+ list<T>::const_iterator it = as.begin();
+ T elem = *it;
+ int count = 0;
+
+ for (; it != as.end(); it++) {
+ if (elem != *it) {
+ runs.push_back(make_pair(elem, count));
+ elem = *it;
+ count = 0;
+ }
+ count += 1;
+ }
+ runs.push_back(make_pair(elem, count));
+ }
+ return runs;
+}
691 slides.html
@@ -0,0 +1,691 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta name="generator" content="pandoc" />
+ <meta name="author" content="Mark Lentczner" />
+ <meta name="date" content="2011-09-29" />
+ <title>Haskell Bits</title>
+ <style type="text/css">
+/*<![CDATA[*/
+table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode, table.sourceCode pre
+ { margin: 0; padding: 0; border: 0; vertical-align: baseline; border: none; }
+td.lineNumbers { border-right: 1px solid #AAAAAA; text-align: right; color: #AAAAAA; padding-right: 5px; padding-left: 5px; }
+td.sourceCode { padding-left: 5px; }
+code.sourceCode span.kw { color: #007020; font-weight: bold; }
+code.sourceCode span.dt { color: #902000; }
+code.sourceCode span.dv { color: #40a070; }
+code.sourceCode span.bn { color: #40a070; }
+code.sourceCode span.fl { color: #40a070; }
+code.sourceCode span.ch { color: #4070a0; }
+code.sourceCode span.st { color: #4070a0; }
+code.sourceCode span.co { color: #60a0b0; font-style: italic; }
+code.sourceCode span.ot { color: #007020; }
+code.sourceCode span.al { color: red; font-weight: bold; }
+code.sourceCode span.fu { color: #06287e; }
+code.sourceCode span.re { }
+code.sourceCode span.er { color: red; font-weight: bold; }
+/*]]>*/
+ </style>
+ <style type="text/css">
+/*<![CDATA[*/
+/* slidy.css
+
+ Copyright (c) 2005-2010 W3C (MIT, ERCIM, Keio), All Rights Reserved.
+ W3C liability, trademark, document use and software licensing
+ rules apply, see:
+
+ http://www.w3.org/Consortium/Legal/copyright-documents
+ http://www.w3.org/Consortium/Legal/copyright-software
+*/
+body
+{
+ margin: 0 0 0 0;
+ padding: 0 0 0 0;
+ width: 100%;
+ height: 100%;
+ color: black;
+ background-color: white;
+ font-family: "Gill Sans MT", "Gill Sans", GillSans, sans-serif;
+ font-size: 14pt;
+}
+
+div.toolbar {
+ position: fixed; z-index: 200;
+ top: auto; bottom: 0; left: 0; right: 0;
+ height: 1.2em; text-align: right;
+ padding-left: 1em;
+ padding-right: 1em;
+ font-size: 60%;
+ color: red;
+ background-color: rgb(240,240,240);
+ border-top: solid 1px rgb(180,180,180);
+}
+
+div.toolbar span.copyright {
+ color: black;
+ margin-left: 0.5em;
+}
+
+div.initial_prompt {
+ position: absolute;
+ z-index: 1000;
+ bottom: 1.2em;
+ width: 100%;
+ background-color: rgb(200,200,200);
+ opacity: 0.35;
+ background-color: rgb(200,200,200, 0.35);
+ cursor: pointer;
+}
+
+div.initial_prompt p.help {
+ text-align: center;
+}
+
+div.initial_prompt p.close {
+ text-align: right;
+ font-style: italic;
+}
+
+div.slidy_toc {
+ position: absolute;
+ z-index: 300;
+ width: 60%;
+ max-width: 30em;
+ height: 30em;
+ overflow: auto;
+ top: auto;
+ right: auto;
+ left: 4em;
+ bottom: 4em;
+ padding: 1em;
+ background: rgb(240,240,240);
+ border-style: solid;
+ border-width: 2px;
+ font-size: 60%;
+}
+
+div.slidy_toc .toc_heading {
+ text-align: center;
+ width: 100%;
+ margin: 0;
+ margin-bottom: 1em;
+ border-bottom-style: solid;
+ border-bottom-color: rgb(180,180,180);
+ border-bottom-width: 1px;
+}
+
+div.slide {
+ z-index: 20;
+ margin: 0 0 0 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ padding-left: 20px;
+ padding-right: 20px;
+ border-width: 0;
+ clear: both;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ line-height: 120%;
+ background-color: transparent;
+}
+
+div.background {
+ display: none;
+}
+
+div.handout {
+ margin-left: 20px;
+ margin-right: 20px;
+}
+
+div.slide.titlepage {
+ text-align: center;
+}
+
+div.slide.titlepage h1 {
+ padding-top: 10%;
+ margin-right: 0;
+}
+
+div.slide h1 {
+ padding-left: 0;
+ padding-right: 20pt;
+ padding-top: 4pt;
+ padding-bottom: 4pt;
+ margin-top: 0;
+ margin-left: 0;
+ margin-right: 60pt;
+ margin-bottom: 0.5em;
+ display: block;
+ font-size: 160%;
+ line-height: 1.2em;
+ background: transparent;
+}
+
+div.toc {
+ position: absolute;
+ top: auto;
+ bottom: 4em;
+ left: 4em;
+ right: auto;
+ width: 60%;
+ max-width: 30em;
+ height: 30em;
+ border: solid thin black;
+ padding: 1em;
+ background: rgb(240,240,240);
+ color: black;
+ z-index: 300;
+ overflow: auto;
+ display: block;
+ visibility: visible;
+}
+
+div.toc-heading {
+ width: 100%;
+ border-bottom: solid 1px rgb(180,180,180);
+ margin-bottom: 1em;
+ text-align: center;
+}
+
+pre {
+ font-size: 80%;
+ font-weight: bold;
+ line-height: 120%;
+ padding-top: 0.2em;
+ padding-bottom: 0.2em;
+ padding-left: 1em;
+ padding-right: 1em;
+ border-style: solid;
+ border-left-width: 1em;
+ border-top-width: thin;
+ border-right-width: thin;
+ border-bottom-width: thin;
+ border-color: #95ABD0;
+ color: #00428C;
+ background-color: #E4E5E7;
+}
+
+li pre { margin-left: 0; }
+
+blockquote { font-style: italic }
+
+img { background-color: transparent }
+
+p.copyright { font-size: smaller }
+
+.center { text-align: center }
+.footnote { font-size: smaller; margin-left: 2em; }
+
+a img { border-width: 0; border-style: none }
+
+a:visited { color: navy }
+a:link { color: navy }
+a:hover { color: red; text-decoration: underline }
+a:active { color: red; text-decoration: underline }
+
+a {text-decoration: none}
+.navbar a:link {color: white}
+.navbar a:visited {color: yellow}
+.navbar a:active {color: red}
+.navbar a:hover {color: red}
+
+ul { list-style-type: square; }
+ul ul { list-style-type: disc; }
+ul ul ul { list-style-type: circle; }
+ul ul ul ul { list-style-type: disc; }
+li { margin-left: 0.5em; margin-top: 0.5em; }
+li li { font-size: 85%; font-style: italic }
+li li li { font-size: 85%; font-style: normal }
+
+div dt
+{
+ margin-left: 0;
+ margin-top: 1em;
+ margin-bottom: 0.5em;
+ font-weight: bold;
+}
+div dd
+{
+ margin-left: 2em;
+ margin-bottom: 0.5em;
+}
+
+
+p,pre,ul,ol,blockquote,h2,h3,h4,h5,h6,dl,table {
+ margin-left: 1em;
+ margin-right: 1em;
+}
+
+p.subhead { font-weight: bold; margin-top: 2em; }
+
+.smaller { font-size: smaller }
+.bigger { font-size: 130% }
+
+td,th { padding: 0.2em }
+
+ul {
+ margin: 0.5em 1.5em 0.5em 1.5em;
+ padding: 0;
+}
+
+ol {
+ margin: 0.5em 1.5em 0.5em 1.5em;
+ padding: 0;
+}
+
+ul { list-style-type: square; }
+ul ul { list-style-type: disc; }
+ul ul ul { list-style-type: circle; }
+ul ul ul ul { list-style-type: disc; }
+
+ul li {
+ list-style: square;
+ margin: 0.1em 0em 0.6em 0;
+ padding: 0 0 0 0;
+ line-height: 140%;
+}
+
+ol li {
+ margin: 0.1em 0em 0.6em 1.5em;
+ padding: 0 0 0 0px;
+ line-height: 140%;
+ list-style-type: decimal;
+}
+
+li ul li {
+ font-size: 85%;
+ font-style: italic;
+ list-style-type: disc;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+li li ul li {
+ font-size: 85%;
+ font-style: normal;
+ list-style-type: circle;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+li li li ul li {
+ list-style-type: disc;
+ background: transparent;
+ padding: 0 0 0 0;
+}
+
+li ol li {
+ list-style-type: decimal;
+}
+
+
+li li ol li {
+ list-style-type: decimal;
+}
+
+/*
+ setting class="outline on ol or ul makes it behave as an
+ ouline list where blocklevel content in li elements is
+ hidden by default and can be expanded or collapsed with
+ mouse click. Set class="expand" on li to override default
+*/
+
+ol.outline li:hover { cursor: pointer }
+ol.outline li.nofold:hover { cursor: default }
+
+ul.outline li:hover { cursor: pointer }
+ul.outline li.nofold:hover { cursor: default }
+
+ol.outline { list-style:decimal; }
+ol.outline ol { list-style-type:lower-alpha }
+
+ol.outline li.nofold {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/nofold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.unfolded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.folded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold-dim.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.unfolded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold.gif) no-repeat 0px 0.5em;
+}
+ol.outline li.folded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold.gif) no-repeat 0px 0.5em;
+}
+
+ul.outline li.nofold {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/nofold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.unfolded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.folded {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold-dim.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.unfolded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/fold.gif) no-repeat 0px 0.5em;
+}
+ul.outline li.folded:hover {
+ padding: 0 0 0 20px;
+ background: transparent url(../graphics/unfold.gif) no-repeat 0px 0.5em;
+}
+
+/* for slides with class "title" in table of contents */
+a.titleslide { font-weight: bold; font-style: italic }
+
+/*
+ hide images for work around for save as bug
+ where browsers fail to save images used by CSS
+*/
+img.hidden { display: none; visibility: hidden }
+div.initial_prompt { display: none; visibility: hidden }
+
+ div.slide {
+ visibility: visible;
+ position: inherit;
+ }
+ div.handout {
+ border-top-style: solid;
+ border-top-width: thin;
+ border-top-color: black;
+ }
+
+@media screen {
+ .hidden { display: none; visibility: visible }
+
+ div.slide.hidden { display: block; visibility: visible }
+ div.handout.hidden { display: block; visibility: visible }
+ div.background { display: none; visibility: hidden }
+ body.single_slide div.initial_prompt { display: block; visibility: visible }
+ body.single_slide div.background { display: block; visibility: visible }
+ body.single_slide div.background.hidden { display: none; visibility: hidden }
+ body.single_slide .invisible { visibility: hidden }
+ body.single_slide .hidden { display: none; visibility: hidden }
+ body.single_slide div.slide { position: absolute }
+ body.single_slide div.handout { display: none; visibility: hidden }
+}
+
+@media print {
+ .hidden { display: block; visibility: visible }
+
+ div.slide pre { font-size: 60%; padding-left: 0.5em; }
+ div.toolbar { display: none; visibility: hidden; }
+ div.slidy_toc { display: none; visibility: hidden; }
+ div.background { display: none; visibility: hidden; }
+ div.slide { page-break-before: always }
+ /* :first-child isn't reliable for print media */
+ div.slide.first-slide { page-break-before: avoid }
+}
+
+/*]]>*/
+ </style>
+<script type="text/javascript" charset="utf-8">
+/*<![CDATA[*/
+var w3c_slidy={ns_pos:(typeof window.pageYOffset!="undefined"),khtml:((navigator.userAgent).indexOf("KHTML")>=0?true:false),opera:((navigator.userAgent).indexOf("Opera")>=0?true:false),ipad:((navigator.userAgent).indexOf("iPad")>=0?true:false),iphone:((navigator.userAgent).indexOf("iPhone")>=0?true:false),ie:(typeof document.all!="undefined"&&!this.opera),ie6:(!this.ns_pos&&navigator.userAgent.indexOf("MSIE 6")!=-1),ie7:(!this.ns_pos&&navigator.userAgent.indexOf("MSIE 7")!=-1),ie8:(!this.ns_pos&&navigator.userAgent.indexOf("MSIE 8")!=-1),ie9:(!this.ns_pos&&navigator.userAgent.indexOf("MSIE 9")!=-1),keyboardless:(this.ipad||this.iphone),is_xhtml:/xml/.test(document.contentType),slide_number:0,slide_number_element:null,slides:[],notes:[],backgrounds:[],toolbar:null,title:null,last_shown:null,eos:null,toc:null,outline:null,selected_text_len:0,view_all:0,want_toolbar:true,mouse_click_enabled:true,scroll_hack:0,disable_slide_click:false,lang:"en",help_anchor:null,help_page:"http://www.w3.org/Talks/Tools/Slidy2/help/help.html",help_text:"Navigate with mouse click, space bar, Cursor Left/Right, or Pg Up and Pg Dn. Use S and B to change font size.",size_index:0,size_adjustment:0,sizes:new Array("10pt","12pt","14pt","16pt","18pt","20pt","22pt","24pt","26pt","28pt","30pt","32pt"),last_width:0,last_height:0,objects:[],set_up:function(){var a=function(){w3c_slidy.init()};if(typeof window.addEventListener!="undefined"){window.addEventListener("load",a,false)}else{window.attachEvent("onload",a)}},hide_slides:function(){if(document.body&&!w3c_slidy.initialized){document.body.style.visibility="hidden"}else{setTimeout(w3c_slidy.hide_slides,50)}},ie_hack:function(){window.resizeBy(0,-1);window.resizeBy(0,1)},init:function(){document.body.style.visibility="visible";this.init_localization();this.add_toolbar();this.wrap_implicit_slides();this.collect_slides();this.collect_notes();this.collect_backgrounds();this.objects=document.body.getElementsByTagName("object");this.patch_anchors();this.slide_number=this.find_slide_number(location.href);window.offscreenbuffering=true;this.size_adjustment=this.find_size_adjust();this.time_left=this.find_duration();this.hide_image_toolbar();this.init_outliner();this.title=document.title;this.is_xhtml=(document.body.tagName=="BODY"?false:true);if(this.slides.length>0){var a=this.slides[this.slide_number];if(this.slide_number>0){this.set_visibility_all_incremental("visible");this.last_shown=this.previous_incremental_item(null);this.set_eos_status(true)}else{this.last_shown=null;this.set_visibility_all_incremental("hidden");this.set_eos_status(!this.next_incremental_item(this.last_shown))}this.set_location();this.add_class(this.slides[0],"first-slide");w3c_slidy.show_slide(a)}this.toc=this.table_of_contents();this.add_initial_prompt();if(!this.keyboardless){this.add_listener(document.body,"click",this.mouse_button_click)}this.add_listener(document,"keydown",this.key_down);this.add_listener(document,"keypress",this.key_press);this.add_listener(window,"resize",this.resized);this.add_listener(window,"scroll",this.scrolled);this.add_listener(window,"unload",this.unloaded);this.single_slide_view();this.resized();if(this.ie7){setTimeout(w3c_slidy.ie_hack,100)}this.show_toolbar();setInterval(function(){w3c_slidy.check_location()},200);w3c_slidy.initialized=true},table_of_contents:function(){var c=this.create_element("div");this.add_class(c,"slidy_toc hidden");var k=this.create_element("div");this.add_class(k,"toc-heading");k.innerHTML=this.localize("Table of Contents");c.appendChild(k);var f=null;for(var d=0;d<this.slides.length;++d){var g=this.has_class(this.slides[d],"title");var e=document.createTextNode((d+1)+". ");c.appendChild(e);var h=this.create_element("a");h.setAttribute("href","#("+(d+1)+")");if(g){this.add_class(h,"titleslide")}var b=document.createTextNode(this.slide_name(d));h.appendChild(b);h.onclick=w3c_slidy.toc_click;h.onkeydown=w3c_slidy.toc_key_down;h.previous=f;if(f){f.next=h}c.appendChild(h);if(d==0){c.first=h}if(d<this.slides.length-1){var j=this.create_element("br");c.appendChild(j)}f=h}c.focus=function(){if(this.first){this.first.focus()}};c.onmouseup=w3c_slidy.mouse_button_up;c.onclick=function(a){a||(a=window.event);if(w3c_slidy.selected_text_len<=0){w3c_slidy.hide_table_of_contents(true)}w3c_slidy.stop_propagation(a);if(a.cancel!=undefined){a.cancel=true}if(a.returnValue!=undefined){a.returnValue=false}return false};document.body.insertBefore(c,document.body.firstChild);return c},is_shown_toc:function(){return !w3c_slidy.has_class(w3c_slidy.toc,"hidden")},show_table_of_contents:function(){w3c_slidy.remove_class(w3c_slidy.toc,"hidden");var a=w3c_slidy.toc;a.focus();if(w3c_slidy.ie7&&w3c_slidy.slide_number==0){setTimeout(w3c_slidy.ie_hack,100)}},hide_table_of_contents:function(a){w3c_slidy.add_class(w3c_slidy.toc,"hidden");if(a&&!w3c_slidy.opera){w3c_slidy.help_anchor.focus()}},toggle_table_of_contents:function(){if(w3c_slidy.is_shown_toc()){w3c_slidy.hide_table_of_contents(true)}else{w3c_slidy.show_table_of_contents()}},toc_click:function(d){if(!d){d=window.event}var c=w3c_slidy.get_target(d);if(c&&c.nodeType==1){var b=c.getAttribute("href");if(b){var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=w3c_slidy.find_slide_number(b);a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.last_shown=null;w3c_slidy.set_location();w3c_slidy.set_visibility_all_incremental("hidden");w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));w3c_slidy.show_slide(a);try{if(!w3c_slidy.opera){w3c_slidy.help_anchor.focus()}}catch(d){}}}w3c_slidy.hide_table_of_contents(true);if(w3c_slidy.ie7){w3c_slidy.ie_hack()}w3c_slidy.stop_propagation(d);return w3c_slidy.cancel(d)},toc_key_down:function(d){var b;if(!d){var d=window.event}if(window.event){b=window.event.keyCode}else{if(d.which){b=d.which}else{return true}}if(!b){return true}if(d.ctrlKey||d.altKey){return true}if(b==13){var c=this.getAttribute("href");if(c){var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=w3c_slidy.find_slide_number(c);a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.last_shown=null;w3c_slidy.set_location();w3c_slidy.set_visibility_all_incremental("hidden");w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));w3c_slidy.show_slide(a);try{if(!w3c_slidy.opera){w3c_slidy.help_anchor.focus()}}catch(f){}}w3c_slidy.hide_table_of_contents(true);if(self.ie7){w3c_slidy.ie_hack()}return w3c_slidy.cancel(d)}if(b==40&&this.next){this.next.focus();return w3c_slidy.cancel(d)}if(b==38&&this.previous){this.previous.focus();return w3c_slidy.cancel(d)}return true},before_print:function(){this.show_all_slides();this.hide_toolbar();alert("before print")},after_print:function(){if(!this.view_all){this.single_slide_view();this.show_toolbar()}alert("after print")},print_slides:function(){this.before_print();window.print();this.after_print()},toggle_view:function(){if(this.view_all){this.single_slide_view();this.show_toolbar();this.view_all=0}else{this.show_all_slides();this.hide_toolbar();this.view_all=1}},show_all_slides:function(){this.remove_class(document.body,"single_slide");this.set_visibility_all_incremental("visible")},single_slide_view:function(){this.add_class(document.body,"single_slide");this.set_visibility_all_incremental("visible");this.last_shown=this.previous_incremental_item(null)},hide_image_toolbar:function(){if(!this.ns_pos){var a=document.getElementsByTagName("IMG");for(var b=0;b<a.length;++b){a[b].setAttribute("galleryimg","no")}}},unloaded:function(a){},is_KHTML:function(){var a=navigator.userAgent;return(a.indexOf("KHTML")>=0?true:false)},slide_name:function(c){var b=null;var a=this.slides[c];var d=this.find_heading(a);if(d){b=this.extract_text(d)}if(!b){b=this.title+"("+(c+1)+")"}b.replace(/\&/g,"&amp;");b.replace(/\</g,"&lt;");b.replace(/\>/g,"&gt;");return b},find_heading:function(a){if(!a||a.nodeType!=1){return null}if(a.nodeName=="H1"||a.nodeName=="h1"){return a}var b=a.firstChild;while(b){a=this.find_heading(b);if(a){return a}b=b.nextSibling}return null},extract_text:function(a){if(!a){return""}if(a.nodeType==3){return a.nodeValue}if(a.nodeType==1){a=a.firstChild;var b="";while(a){b=b+this.extract_text(a);a=a.nextSibling}return b}return""},find_copyright:function(){var a,c;var d=document.getElementsByTagName("meta");for(var b=0;b<d.length;++b){a=d[b].getAttribute("name");c=d[b].getAttribute("content");if(a=="copyright"){return c}}return null},find_size_adjust:function(){var a,c,e;var d=document.getElementsByTagName("meta");for(var b=0;b<d.length;++b){a=d[b].getAttribute("name");c=d[b].getAttribute("content");if(a=="font-size-adjustment"){return 1*c}}return 1},find_duration:function(){var a,c,e;var d=document.getElementsByTagName("meta");for(var b=0;b<d.length;++b){a=d[b].getAttribute("name");c=d[b].getAttribute("content");if(a=="duration"){return 60000*c}}return null},replace_by_non_breaking_space:function(b){for(var a=0;a<b.length;++a){b[a]=160}},init_outliner:function(){var a=document.getElementsByTagName("li");for(var b=0;b<a.length;++b){var c=a[b];if(!this.has_class(c.parentNode,"outline")){continue}c.onclick=this.outline_click;if(this.foldable(c)){c.foldable=true;c.onfocus=function(){w3c_slidy.outline=this};c.onblur=function(){w3c_slidy.outline=null};if(!c.getAttribute("tabindex")){c.setAttribute("tabindex","0")}if(this.has_class(c,"expand")){this.unfold(c)}else{this.fold(c)}}else{this.add_class(c,"nofold");c.visible=true;c.foldable=false}}},foldable:function(b){if(!b||b.nodeType!=1){return false}var a=b.firstChild;while(a){if(a.nodeType==1&&this.is_block(a)){return true}a=a.nextSibling}return false},fold:function(b){if(b){this.remove_class(b,"unfolded");this.add_class(b,"folded")}var a=b?b.firstChild:null;while(a){if(a.nodeType==1&&this.is_block(a)){w3c_slidy.add_class(a,"hidden")}a=a.nextSibling}b.visible=false},unfold:function(b){if(b){this.add_class(b,"unfolded");this.remove_class(b,"folded")}var a=b?b.firstChild:null;while(a){if(a.nodeType==1&&this.is_block(a)){w3c_slidy.remove_class(a,"hidden")}a=a.nextSibling}b.visible=true},outline_click:function(c){if(!c){c=window.event}var a=false;var b=w3c_slidy.get_target(c);while(b&&b.visible==undefined){b=b.parentNode}if(!b){return true}if(c.which){a=(c.which==3)}else{if(c.button){a=(c.button==2)}}if(!a&&b.visible!=undefined){if(b.foldable){if(b.visible){w3c_slidy.fold(b)}else{w3c_slidy.unfold(b)}}w3c_slidy.stop_propagation(c);c.cancel=true;c.returnValue=false}return false},add_initial_prompt:function(){var a=this.create_element("div");a.setAttribute("class","initial_prompt");var b=this.create_element("p");a.appendChild(b);b.setAttribute("class","help");if(this.keyboardless){b.innerHTML="Tap footer to move to next slide"}else{b.innerHTML="Space or Right Arrow to move to next slide, click help below for more details"}this.add_listener(a,"click",function(c){document.body.removeChild(a);w3c_slidy.stop_propagation(c);if(c.cancel!=undefined){c.cancel=true}if(c.returnValue!=undefined){c.returnValue=false}return false});document.body.appendChild(a);this.initial_prompt=a;setTimeout(function(){document.body.removeChild(a)},5000)},add_toolbar:function(){var a,i;this.toolbar=this.create_element("div");this.toolbar.setAttribute("class","toolbar");if(this.ns_pos||!this.ie6){var k=this.create_element("div");k.setAttribute("style","float: right; text-align: right");a=this.create_element("span");a.innerHTML=this.localize("slide")+" n/m";k.appendChild(a);this.toolbar.appendChild(k);var e=this.create_element("div");e.setAttribute("style","text-align: left");this.eos=this.create_element("span");this.eos.innerHTML="* ";e.appendChild(this.eos);var g=this.create_element("a");g.setAttribute("href",this.help_page);g.setAttribute("title",this.localize(this.help_text));g.innerHTML=this.localize("help?");e.appendChild(g);this.help_anchor=g;var d=document.createTextNode(" ");e.appendChild(d);var f=this.create_element("a");f.setAttribute("href","javascript:w3c_slidy.toggle_table_of_contents()");f.setAttribute("title",this.localize("table of contents"));f.innerHTML=this.localize("contents?");e.appendChild(f);var b=document.createTextNode(" ");e.appendChild(b);var h=this.find_copyright();if(h){var j=this.create_element("span");j.className="copyright";j.innerHTML=h;e.appendChild(j)}this.toolbar.setAttribute("tabindex","0");this.toolbar.appendChild(e)}else{this.toolbar.style.position=(this.ie7?"fixed":"absolute");this.toolbar.style.zIndex="200";this.toolbar.style.width="99.9%";this.toolbar.style.height="1.2em";this.toolbar.style.top="auto";this.toolbar.style.bottom="0";this.toolbar.style.left="0";this.toolbar.style.right="0";this.toolbar.style.textAlign="left";this.toolbar.style.fontSize="60%";this.toolbar.style.color="red";this.toolbar.borderWidth=0;this.toolbar.className="toolbar";this.toolbar.style.background="rgb(240,240,240)";var c=this.create_element("span");c.innerHTML="&nbsp;&nbsp;*&nbsp;";this.toolbar.appendChild(c);this.eos=c;var g=this.create_element("a");g.setAttribute("href",this.help_page);g.setAttribute("title",this.localize(this.help_text));g.innerHTML=this.localize("help?");this.toolbar.appendChild(g);this.help_anchor=g;var d=document.createTextNode(" ");this.toolbar.appendChild(d);var f=this.create_element("a");f.setAttribute("href","javascript:toggleTableOfContents()");f.setAttribute("title",this.localize("table of contents".localize));f.innerHTML=this.localize("contents?");this.toolbar.appendChild(f);var b=document.createTextNode(" ");this.toolbar.appendChild(b);var h=this.find_copyright();if(h){var j=this.create_element("span");j.innerHTML=h;j.style.color="black";j.style.marginLeft="0.5em";this.toolbar.appendChild(j)}a=this.create_element("div");a.style.position="absolute";a.style.width="auto";a.style.height="1.2em";a.style.top="auto";a.style.bottom=0;a.style.right="0";a.style.textAlign="right";a.style.color="red";a.style.background="rgb(240,240,240)";a.innerHTML=this.localize("slide")+" n/m";this.toolbar.appendChild(a)}this.toolbar.onclick=function(m){if(!m){m=window.event}var l=m.target;if(!l&&m.srcElement){l=m.srcElement}if(l&&l.nodeType==3){l=l.parentNode}w3c_slidy.stop_propagation(m);if(l&&l.nodeName.toLowerCase()!="a"){w3c_slidy.mouse_button_click(m)}};this.slide_number_element=a;this.set_eos_status(false);document.body.appendChild(this.toolbar)},wrap_implicit_slides:function(){var a,d,c,b,f;var e=document.getElementsByTagName("h1");if(!e){return}for(a=0;a<e.length;++a){d=e[a];if(d.parentNode!=document.body){continue}c=d.nextSibling;f=document.createElement("div");this.add_class(f,"slide");document.body.replaceChild(f,d);f.appendChild(d);while(c){if(c.nodeType==1&&(c.nodeName=="H1"||c.nodeName=="h1"||c.nodeName=="DIV"||c.nodeName=="div")){break}b=c.nextSibling;c=document.body.removeChild(c);f.appendChild(c);c=b}}},collect_slides:function(){var e=new Array();var d=document.body.getElementsByTagName("div");for(var c=0;c<d.length;++c){div=d.item(c);if(this.has_class(div,"slide")){e[e.length]=div;this.add_class(div,"hidden");var b=document.createElement("br");div.appendChild(b);var a=document.createElement("br");div.appendChild(a)}else{if(this.has_class(div,"background")){div.style.display="block"}}}this.slides=e},collect_notes:function(){var b=new Array();var c=document.body.getElementsByTagName("div");for(var a=0;a<c.length;++a){div=c.item(a);if(this.has_class(div,"handout")){b[b.length]=div;this.add_class(div,"hidden")}}this.notes=b},collect_backgrounds:function(){var c=new Array();var b=document.body.getElementsByTagName("div");for(var a=0;a<b.length;++a){div=b.item(a);if(this.has_class(div,"background")){c[c.length]=div;this.add_class(div,"hidden")}}this.backgrounds=c},patch_anchors:function(){var a=w3c_slidy;var c=function(g){if(a.page_address(this.href)==a.page_address(location.href)){var f=a.find_slide_number(this.href);if(f!=a.slide_number){var e=a.slides[a.slide_number];a.hide_slide(e);a.slide_number=f;e=a.slides[a.slide_number];a.show_slide(e);a.set_location()}}else{w3c_slidy.stop_propagation(g)}this.blur();a.disable_slide_click=true};var d=document.body.getElementsByTagName("a");for(var b=0;b<d.length;++b){if(window.addEventListener){d[b].addEventListener("click",c,false)}else{d[b].attachEvent("onclick",c)}}},show_slide_number:function(){var a=w3c_slidy.get_timer();w3c_slidy.slide_number_element.innerHTML=a+w3c_slidy.localize("slide")+" "+(w3c_slidy.slide_number+1)+"/"+w3c_slidy.slides.length},check_location:function(){var b=location.hash;if(w3c_slidy.slide_number>0&&(b==""||b=="#")){w3c_slidy.goto_slide(0)}else{if(b.length>2&&b!="#("+(w3c_slidy.slide_number+1)+")"){var a=parseInt(location.hash.substr(2));if(!isNaN(a)){w3c_slidy.goto_slide(a-1)}}}if(w3c_slidy.time_left&&w3c_slidy.slide_number>0){w3c_slidy.show_slide_number();if(w3c_slidy.time_left>0){w3c_slidy.time_left-=200}}},get_timer:function(){var c="";if(w3c_slidy.time_left){var b,a;a=Math.floor(w3c_slidy.time_left/1000);b=Math.floor(a/60);a=a%60;c=(b?b+"m":"")+a+"s "}return c},set_location:function(){var a=w3c_slidy.page_address(location.href);var b="#("+(w3c_slidy.slide_number+1)+")";if(w3c_slidy.slide_number>=0){a=a+b}if(w3c_slidy.ie&&(w3c_slidy.ie6||w3c_slidy.ie7)){w3c_slidy.push_hash(b)}if(a!=location.href){location.href=a}if(this.khtml){b="("+(w3c_slidy.slide_number+1)+")"}if(!this.ie&&location.hash!=b&&location.hash!=""){location.hash=b}document.title=w3c_slidy.title+" ("+(w3c_slidy.slide_number+1)+")";w3c_slidy.show_slide_number()},page_address:function(b){var a=b.indexOf("#");if(a<0){a=b.indexOf("%23")}if(a<0){return b}return b.substr(0,a)},on_frame_loaded:function(b){location.hash=b;var a=w3c_slidy.page_address(location.href);location.href=a+b},push_hash:function(b){if(b==""){b="#(1)"}window.location.hash=b;var a=document.getElementById("historyFrame").contentWindow.document;a.open("javascript:'<html></html>'");a.write('<html><head><script type="text/javascript">window.parent.w3c_slidy.on_frame_loaded(\''+(b)+"');\74/script></head><body>hello mum</body></html>");a.close()},find_slide_number:function(e){var c=e.indexOf("#");if(c<0){return 0}var b=unescape(e.substr(c+1));var f=document.getElementById(b);if(!f){var d=/\((\d)+\)/;if(b.match(d)){var a=parseInt(b.substring(1,b.length-1));if(a>this.slides.length){a=1}if(--a<0){a=0}return a}d=/\[(\d)+\]/;if(b.match(d)){var a=parseInt(b.substring(1,b.length-1));if(a>this.slides.length){a=1}if(--a<0){a=0}return a}return 0}while(true){if(f.nodeName.toLowerCase()=="div"&&this.has_class(f,"slide")){break}f=f.parentNode;if(!f){return 0}}for(c=0;c<slides.length;++c){if(slides[c]==f){return c}}return 0},previous_slide:function(b){if(!w3c_slidy.view_all){var a;if((b||w3c_slidy.slide_number==0)&&w3c_slidy.last_shown!=null){w3c_slidy.last_shown=w3c_slidy.hide_previous_item(w3c_slidy.last_shown);w3c_slidy.set_eos_status(false)}else{if(w3c_slidy.slide_number>0){a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=w3c_slidy.slide_number-1;a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.set_visibility_all_incremental("visible");w3c_slidy.last_shown=w3c_slidy.previous_incremental_item(null);w3c_slidy.set_eos_status(true);w3c_slidy.show_slide(a)}}w3c_slidy.set_location();if(!w3c_slidy.ns_pos){w3c_slidy.refresh_toolbar(200)}}},next_slide:function(c){if(!w3c_slidy.view_all){var a,b=w3c_slidy.last_shown;if(c||w3c_slidy.slide_number==w3c_slidy.slides.length-1){w3c_slidy.last_shown=w3c_slidy.reveal_next_item(w3c_slidy.last_shown)}if((!c||w3c_slidy.last_shown==null)&&w3c_slidy.slide_number<w3c_slidy.slides.length-1){a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=w3c_slidy.slide_number+1;a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.last_shown=null;w3c_slidy.set_visibility_all_incremental("hidden");w3c_slidy.show_slide(a)}else{if(!w3c_slidy.last_shown){if(b&&c){w3c_slidy.last_shown=b}}}w3c_slidy.set_location();w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));if(!w3c_slidy.ns_pos){w3c_slidy.refresh_toolbar(200)}}},first_slide:function(){if(!w3c_slidy.view_all){var a;if(w3c_slidy.slide_number!=0){a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=0;a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.last_shown=null;w3c_slidy.set_visibility_all_incremental("hidden");w3c_slidy.show_slide(a)}w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));w3c_slidy.set_location()}},last_slide:function(){if(!w3c_slidy.view_all){var a;w3c_slidy.last_shown=null;if(w3c_slidy.last_shown==null&&w3c_slidy.slide_number<w3c_slidy.slides.length-1){a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=w3c_slidy.slides.length-1;a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.set_visibility_all_incremental("visible");w3c_slidy.last_shown=w3c_slidy.previous_incremental_item(null);w3c_slidy.show_slide(a)}else{w3c_slidy.set_visibility_all_incremental("visible");w3c_slidy.last_shown=w3c_slidy.previous_incremental_item(null)}w3c_slidy.set_eos_status(true);w3c_slidy.set_location()}},set_eos_status:function(a){if(this.eos){this.eos.style.color=(a?"rgb(240,240,240)":"red")}},goto_slide:function(b){var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.slide_number=b;a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.last_shown=null;w3c_slidy.set_visibility_all_incremental("hidden");w3c_slidy.set_eos_status(!w3c_slidy.next_incremental_item(w3c_slidy.last_shown));document.title=w3c_slidy.title+" ("+(w3c_slidy.slide_number+1)+")";w3c_slidy.show_slide(a);w3c_slidy.show_slide_number()},show_slide:function(a){this.sync_background(a);window.scrollTo(0,0);this.remove_class(a,"hidden")},hide_slide:function(a){this.add_class(a,"hidden")},sync_background:function(a){var e;var g;if(a.currentStyle){g=a.currentStyle.backgroundColor}else{if(document.defaultView){var f=document.defaultView.getComputedStyle(a,null);if(f){g=f.getPropertyValue("background-color")}else{g="transparent"}}else{g=="transparent"}}if(g=="transparent"||g.indexOf("rgba")>=0||g.indexOf("opacity")>=0){var c=this.get_class_list(a);for(var d=0;d<this.backgrounds.length;d++){e=this.backgrounds[d];var b=this.get_class_list(e);if(this.matching_background(c,b)){this.remove_class(e,"hidden")}else{this.add_class(e,"hidden")}}}else{this.hide_backgrounds()}},hide_backgrounds:function(){for(var a=0;a<this.backgrounds.length;a++){background=this.backgrounds[a];this.add_class(background,"hidden")}},matching_background:function(c,b){var d,e,f,a;f=/\w+/g;a=b.match(f);for(d=e=0;d<a.length;d++){if(a[d]=="hidden"){continue}if(a[d]=="background"){continue}++e}if(e==0){return true}a=c.match(f);for(d=e=0;d<a.length;d++){if(a[d]=="hidden"){continue}if(this.has_token(b,a[d])){return true}}return false},resized:function(){var c=0;if(typeof(window.innerWidth)=="number"){c=window.innerWidth}else{if(document.documentElement&&document.documentElement.clientWidth){c=document.documentElement.clientWidth}else{if(document.body&&document.body.clientWidth){c=document.body.clientWidth}}}var b=0;if(typeof(window.innerHeight)=="number"){b=window.innerHeight}else{if(document.documentElement&&document.documentElement.clientHeight){b=document.documentElement.clientHeight}else{if(document.body&&document.body.clientHeight){b=document.body.clientHeight}}}if(b&&(c/b>1.05*1024/768)){c=b*1024/768}if(c!=w3c_slidy.last_width||b!=w3c_slidy.last_height){if(c>=1100){w3c_slidy.size_index=5}else{if(c>=1000){w3c_slidy.size_index=4}else{if(c>=800){w3c_slidy.size_index=3}else{if(c>=600){w3c_slidy.size_index=2}else{if(c){w3c_slidy.size_index=0}}}}}if(0<=w3c_slidy.size_index+w3c_slidy.size_adjustment&&w3c_slidy.size_index+w3c_slidy.size_adjustment<w3c_slidy.sizes.length){w3c_slidy.size_index=w3c_slidy.size_index+w3c_slidy.size_adjustment}w3c_slidy.adjust_object_dimensions(c,b);if(document.body.style.fontSize!=w3c_slidy.sizes[w3c_slidy.size_index]){document.body.style.fontSize=w3c_slidy.sizes[w3c_slidy.size_index]}w3c_slidy.last_width=c;w3c_slidy.last_height=b;if(w3c_slidy.ns_pos){var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.show_slide(a)}w3c_slidy.refresh_toolbar(200)}},scrolled:function(){if(w3c_slidy.toolbar&&!w3c_slidy.ns_pos&&!w3c_slidy.ie7){w3c_slidy.hack_offset=w3c_slidy.scroll_x_offset();w3c_slidy.toolbar.style.display="none";if(w3c_slidy.scrollhack==0&&!w3c_slidy.view_all){setTimeout(function(){w3c_slidy.show_toolbar()},1000);w3c_slidy.scrollhack=1}}},hide_toolbar:function(){w3c_slidy.add_class(w3c_slidy.toolbar,"hidden");window.focus()},refresh_toolbar:function(a){if(!w3c_slidy.ns_pos&&!w3c_slidy.ie7){w3c_slidy.hide_toolbar();setTimeout(function(){w3c_slidy.show_toolbar()},a)}},show_toolbar:function(){if(w3c_slidy.want_toolbar){w3c_slidy.toolbar.style.display="block";if(!w3c_slidy.ns_pos){var b=w3c_slidy.scroll_x_offset();w3c_slidy.toolbar.style.left=b;w3c_slidy.toolbar.style.right=b;w3c_slidy.toolbar.style.bottom=0}w3c_slidy.remove_class(w3c_slidy.toolbar,"hidden")}w3c_slidy.scrollhack=0;try{if(!w3c_slidy.opera){w3c_slidy.help_anchor.focus()}}catch(a){}},toggle_toolbar:function(){if(!w3c_slidy.view_all){if(w3c_slidy.has_class(w3c_slidy.toolbar,"hidden")){w3c_slidy.remove_class(w3c_slidy.toolbar,"hidden");w3c_slidy.want_toolbar=1}else{w3c_slidy.add_class(w3c_slidy.toolbar,"hidden");w3c_slidy.want_toolbar=0}}},scroll_x_offset:function(){if(window.pageXOffset){return self.pageXOffset}if(document.documentElement&&document.documentElement.scrollLeft){return document.documentElement.scrollLeft}if(document.body){return document.body.scrollLeft}return 0},scroll_y_offset:function(){if(window.pageYOffset){return self.pageYOffset}if(document.documentElement&&document.documentElement.scrollTop){return document.documentElement.scrollTop}if(document.body){return document.body.scrollTop}return 0},optimize_font_size:function(){var a=w3c_slidy.slides[w3c_slidy.slide_number];var d=a.scrollHeight;var b=getWindowHeight();var c=100*d/b;alert("window utilization = "+c+"% (doc "+d+" win "+b+")")},get_doc_height:function(a){if(!a){a=document}if(a&&a.body&&a.body.offsetHeight){return a.body.offsetHeight}if(a&&a.body&&a.body.scrollHeight){return a.body.scrollHeight}alert("couldn't determine document height")},get_window_height:function(){if(typeof(window.innerHeight)=="number"){return window.innerHeight}if(document.documentElement&&document.documentElement.clientHeight){return document.documentElement.clientHeight}if(document.body&&document.body.clientHeight){return document.body.clientHeight}},document_height:function(){var a,b;a=document.body.scrollHeight;b=document.body.offsetHeight;if(a&&b){return(a>b?a:b)}return 0},smaller:function(){if(w3c_slidy.size_index>0){--w3c_slidy.size_index}w3c_slidy.toolbar.style.display="none";document.body.style.fontSize=w3c_slidy.sizes[w3c_slidy.size_index];var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.show_slide(a);setTimeout(function(){w3c_slidy.show_toolbar()},50)},bigger:function(){if(w3c_slidy.size_index<w3c_slidy.sizes.length-1){++w3c_slidy.size_index}w3c_slidy.toolbar.style.display="none";document.body.style.fontSize=w3c_slidy.sizes[w3c_slidy.size_index];var a=w3c_slidy.slides[w3c_slidy.slide_number];w3c_slidy.hide_slide(a);w3c_slidy.show_slide(a);setTimeout(function(){w3c_slidy.show_toolbar()},50)},adjust_object_dimensions:function(c,k){for(var e=0;e<w3c_slidy.objects.length;e++){var d=this.objects[e];var b=d.getAttribute("type");if(b=="image/svg+xml"||b=="application/x-shockwave-flash"){if(!d.initialWidth){d.initialWidth=d.getAttribute("width")}if(!d.initialHeight){d.initialHeight=d.getAttribute("height")}if(d.initialWidth&&d.initialWidth.charAt(d.initialWidth.length-1)=="%"){var j=parseInt(d.initialWidth.slice(0,d.initialWidth.length-1));var a=c*(j/100);d.setAttribute("width",a)}if(d.initialHeight&&d.initialHeight.charAt(d.initialHeight.length-1)=="%"){var f=parseInt(d.initialHeight.slice(0,d.initialHeight.length-1));var g=k*(f/100);d.setAttribute("height",g)}}}},key_press:function(a){if(!a){a=window.event}if(!w3c_slidy.key_wanted){return w3c_slidy.cancel(a)}return true},key_down:function(d){var c,e,a;w3c_slidy.key_wanted=true;if(!d){d=window.event}if(window.event){c=window.event.keyCode;e=window.event.srcElement}else{if(d.which){c=d.which;e=d.target}else{return true}}if(!c){return true}if(!w3c_slidy.slidy_chrome(e)&&w3c_slidy.special_element(e)){return true}if(d.ctrlKey||d.altKey||d.metaKey){return true}if(w3c_slidy.is_shown_toc()&&c!=9&&c!=16&&c!=38&&c!=40){w3c_slidy.hide_table_of_contents(true);if(c==27||c==84||c==67){return w3c_slidy.cancel(d)}}if(c==34){if(w3c_slidy.view_all){return true}w3c_slidy.next_slide(false);return w3c_slidy.cancel(d)}else{if(c==33){if(w3c_slidy.view_all){return true}w3c_slidy.previous_slide(false);return w3c_slidy.cancel(d)}else{if(c==32){w3c_slidy.next_slide(true);return w3c_slidy.cancel(d)}else{if(c==37){w3c_slidy.previous_slide(!d.shiftKey);return w3c_slidy.cancel(d)}else{if(c==36){w3c_slidy.first_slide();return w3c_slidy.cancel(d)}else{if(c==35){w3c_slidy.last_slide();return w3c_slidy.cancel(d)}else{if(c==39){w3c_slidy.next_slide(!d.shiftKey);return w3c_slidy.cancel(d)}else{if(c==13){if(w3c_slidy.outline){if(w3c_slidy.outline.visible){w3c_slidy.fold(w3c_slidy.outline)}else{w3c_slidy.unfold(w3c_slidy.outline)}return w3c_slidy.cancel(d)}}else{if(c==188){w3c_slidy.smaller();return w3c_slidy.cancel(d)}else{if(c==190){w3c_slidy.bigger();return w3c_slidy.cancel(d)}else{if(c==189||c==109){w3c_slidy.smaller();return w3c_slidy.cancel(d)}else{if(c==187||c==191||c==107){w3c_slidy.bigger();return w3c_slidy.cancel(d)}else{if(c==83){w3c_slidy.smaller();return w3c_slidy.cancel(d)}else{if(c==66){w3c_slidy.bigger();return w3c_slidy.cancel(d)}else{if(c==90){w3c_slidy.last_slide();return w3c_slidy.cancel(d)}else{if(c==70){w3c_slidy.toggle_toolbar();return w3c_slidy.cancel(d)}else{if(c==65){w3c_slidy.toggle_view();return w3c_slidy.cancel(d)}else{if(c==75){w3c_slidy.mouse_click_enabled=!w3c_slidy.mouse_click_enabled;var b=(w3c_slidy.mouse_click_enabled?"enabled":"disabled")+" mouse click advance";alert(w3c_slidy.localize(b));return w3c_slidy.cancel(d)}else{if(c==84||c==67){if(w3c_slidy.toc){w3c_slidy.toggle_table_of_contents()}return w3c_slidy.cancel(d)}else{if(c==72){window.location=w3c_slidy.help_page;return w3c_slidy.cancel(d)}}}}}}}}}}}}}}}}}}}}return true},create_element:function(a){if(this.xhtml&&(typeof document.createElementNS!="undefined")){return document.createElementNS("http://www.w3.org/1999/xhtml",a)}return document.createElement(a)},get_element_style:function(d,b,c){if(d.currentStyle){return d.currentStyle[b]}else{if(window.getComputedStyle){var a=window.getComputedStyle(d,"");return a.getPropertyValue(c)}}return""},has_token:function(e,c){if(e){var d=/\w+/g;var a=e.match(d);for(var b=0;b<a.length;b++){if(a[b]==c){return true}}}return false},get_class_list:function(a){if(typeof a.className!="undefined"){return a.className}return a.getAttribute("class")},has_class:function(b,a){if(b.nodeType!=1){return false}var c=new RegExp("(^| )"+a+"W*");if(typeof b.className!="undefined"){return c.test(b.className)}return c.test(b.getAttribute("class"))},remove_class:function(b,a){var d=new RegExp("(^| )"+a+"W*");var c="";if(typeof b.className!="undefined"){c=b.className;if(c){c=c.replace(d,"");b.className=c}}else{c=b.getAttribute("class");if(c){c=c.replace(d,"");b.setAttribute("class",c)}}},add_class:function(b,a){if(!this.has_class(b,a)){if(typeof b.className!="undefined"){b.className+=" "+a}else{var c=b.getAttribute("class");c=c?c+" "+a:a;b.setAttribute("class",c)}}},incremental_elements:null,okay_for_incremental:function(a){if(!this.incremental_elements){var b=new Array();b.p=true;b.pre=true;b.li=true;b.blockquote=true;b.dt=true;b.dd=true;b.h2=true;b.h3=true;b.h4=true;b.h5=true;b.h6=true;b.span=true;b.address=true;b.table=true;b.tr=true;b.th=true;b.td=true;b.img=true;b.object=true;this.incremental_elements=b}return this.incremental_elements[a.toLowerCase()]},next_incremental_item:function(c){var b=this.is_xhtml?"br":"BR";var a=w3c_slidy.slides[w3c_slidy.slide_number];for(;;){c=w3c_slidy.next_node(a,c);if(c==null||c.parentNode==null){break}if(c.nodeType==1){if(c.nodeName==b){continue}if(w3c_slidy.has_class(c,"incremental")&&w3c_slidy.okay_for_incremental(c.nodeName)){return c}if(w3c_slidy.has_class(c.parentNode,"incremental")&&!w3c_slidy.has_class(c,"non-incremental")){return c}}}return c},previous_incremental_item:function(c){var b=this.is_xhtml?"br":"BR";var a=w3c_slidy.slides[w3c_slidy.slide_number];for(;;){c=w3c_slidy.previous_node(a,c);if(c==null||c.parentNode==null){break}if(c.nodeType==1){if(c.nodeName==b){continue}if(w3c_slidy.has_class(c,"incremental")&&w3c_slidy.okay_for_incremental(c.nodeName)){return c}if(w3c_slidy.has_class(c.parentNode,"incremental")&&!w3c_slidy.has_class(c,"non-incremental")){return c}}}return c},set_visibility_all_incremental:function(b){var a=this.next_incremental_item(null);if(b=="hidden"){while(a){w3c_slidy.add_class(a,"invisible");a=w3c_slidy.next_incremental_item(a)}}else{while(a){w3c_slidy.remove_class(a,"invisible");a=w3c_slidy.next_incremental_item(a)}}},reveal_next_item:function(a){a=w3c_slidy.next_incremental_item(a);if(a&&a.nodeType==1){w3c_slidy.remove_class(a,"invisible")}return a},hide_previous_item:function(a){if(a&&a.nodeType==1){w3c_slidy.add_class(a,"invisible")}return this.previous_incremental_item(a)},next_node:function(a,b){if(b==null){return a.firstChild}if(b.firstChild){return b.firstChild}if(b.nextSibling){return b.nextSibling}for(;;){b=b.parentNode;if(!b||b==a){break}if(b&&b.nextSibling){return b.nextSibling}}return null},previous_node:function(a,b){if(b==null){b=a.lastChild;if(b){while(b.lastChild){b=b.lastChild}}return b}if(b.previousSibling){b=b.previousSibling;while(b.lastChild){b=b.lastChild}return b}if(b.parentNode!=a){return b.parentNode}return null},previous_sibling_element:function(a){a=a.previousSibling;while(a&&a.nodeType!=1){a=a.previousSibling}return a},next_sibling_element:function(a){a=a.nextSibling;while(a&&a.nodeType!=1){a=a.nextSibling}return a},first_child_element:function(a){var b;for(b=a.firstChild;b;b=b.nextSibling){if(b.nodeType==1){break}}return b},first_tag:function(b,a){var c;if(!this.is_xhtml){a=a.toUpperCase()}for(c=b.firstChild;c;c=c.nextSibling){if(c.nodeType==1&&c.nodeName==a){break}}return c},hide_selection:function(){if(window.getSelection){var b=window.getSelection();if(b.rangeCount>0){var a=b.getRangeAt(0);a.collapse(false)}}else{var c=document.selection.createRange();c.collapse(false)}},get_selected_text:function(){try{if(window.getSelection){return window.getSelection().toString()}if(document.getSelection){return document.getSelection().toString()}if(document.selection){return document.selection.createRange().text}}catch(a){}return""},mouse_button_up:function(a){w3c_slidy.selected_text_len=w3c_slidy.get_selected_text().length},mouse_button_click:function(g){var c=false;var b=false;var d=false;var f;if(!g){var g=window.event}if(g.target){f=g.target}else{if(g.srcElement){f=g.srcElement}}if(f.nodeType==3){f=f.parentNode}if(g.which){b=(g.which==1);d=(g.which==2);c=(g.which==3)}else{if(g.button){if(g.button==4){d=true}c=(g.button==2)}else{b=true}}if(w3c_slidy.selected_text_len>0){w3c_slidy.stop_propagation(g);g.cancel=true;g.returnValue=false;return false}w3c_slidy.hide_table_of_contents(false);var a=f.nodeName.toLowerCase();if(w3c_slidy.mouse_click_enabled&&b&&!w3c_slidy.special_element(f)&&!f.onclick){w3c_slidy.next_slide(true);w3c_slidy.stop_propagation(g);g.cancel=true;g.returnValue=false;return false}return true},special_element:function(b){var a=b.nodeName.toLowerCase();return b.onkeydown||b.onclick||a=="a"||a=="embed"||a=="object"||a=="video"||a=="audio"||a=="input"||a=="textarea"||a=="select"||a=="option"},slidy_chrome:function(a){while(a){if(a==w3c_slidy.toc||a==w3c_slidy.toolbar||w3c_slidy.has_class(a,"outline")){return true}a=a.parentNode}return false},get_key:function(b){var a;if(typeof window.event!="undefined"){a=window.event.keyCode}else{if(b.which){a=b.which}}return a},get_target:function(b){var a;if(!b){b=window.event}if(b.target){a=b.target}else{if(b.srcElement){a=b.srcElement}}if(a.nodeType!=1){a=a.parentNode}return a},is_block:function(b){var a=b.nodeName.toLowerCase();return a=="ol"||a=="ul"||a=="p"||a=="li"||a=="table"||a=="pre"||a=="h1"||a=="h2"||a=="h3"||a=="h4"||a=="h5"||a=="h6"||a=="blockquote"||a=="address"},add_listener:function(a,c,b){if(window.addEventListener){a.addEventListener(c,b,false)}else{a.attachEvent("on"+c,b)}},stop_propagation:function(a){a=a?a:window.event;a.cancelBubble=true;if(a.stopPropagation){a.stopPropagation()}return true},cancel:function(a){if(a){a.cancel=true;a.returnValue=false;if(a.preventDefault){a.preventDefault()}}w3c_slidy.key_wanted=false;return false},strings_es:{slide:"pág.","help?":"Ayuda","contents?":"Índice","table of contents":"tabla de contenidos","Table of Contents":"Tabla de Contenidos","restart presentation":"Reiniciar presentación","restart?":"Inicio"},help_es:"Utilice el ratón, barra espaciadora, teclas Izda/Dcha, o Re pág y Av pág. Use S y B para cambiar el tamaño de fuente.",strings_ca:{slide:"pàg..","help?":"Ajuda","contents?":"Índex","table of contents":"taula de continguts","Table of Contents":"Taula de Continguts","restart presentation":"Reiniciar presentació","restart?":"Inici"},help_ca:"Utilitzi el ratolí, barra espaiadora, tecles Esq./Dta. o Re pàg y Av pàg. Usi S i B per canviar grandària de font.",strings_cs:{slide:"snímek","help?":"nápověda","contents?":"obsah","table of contents":"obsah prezentace","Table of Contents":"Obsah prezentace","restart presentation":"znovu spustit prezentaci","restart?":"restart"},help_cs:"Prezentaci můžete procházet pomocí kliknutí myši, mezerníku, šipek vlevo a vpravo nebo kláves PageUp a PageDown. Písmo se dá zvětšit a zmenšit pomocí kláves B a S.",strings_nl:{slide:"pagina","help?":"Help?","contents?":"Inhoud?","table of contents":"inhoudsopgave","Table of Contents":"Inhoudsopgave","restart presentation":"herstart presentatie","restart?":"Herstart?"},help_nl:"Navigeer d.m.v. het muis, spatiebar, Links/Rechts toetsen, of PgUp en PgDn. Gebruik S en B om de karaktergrootte te veranderen.",strings_de:{slide:"Seite","help?":"Hilfe","contents?":"Übersicht","table of contents":"Inhaltsverzeichnis","Table of Contents":"Inhaltsverzeichnis","restart presentation":"Präsentation neu starten","restart?":"Neustart"},help_de:"Benutzen Sie die Maus, Leerschlag, die Cursortasten links/rechts oder Page up/Page Down zum Wechseln der Seiten und S und B für die Schriftgrösse.",strings_pl:{slide:"slajd","help?":"pomoc?","contents?":"spis treści?","table of contents":"spis treści","Table of Contents":"Spis Treści","restart presentation":"Restartuj prezentację","restart?":"restart?"},help_pl:"Zmieniaj slajdy klikając myszą, naciskając spację, strzałki lewo/prawolub PgUp / PgDn. Użyj klawiszy S i B, aby zmienić rozmiar czczionki.",strings_fr:{slide:"page","help?":"Aide","contents?":"Index","table of contents":"table des matières","Table of Contents":"Table des matières","restart presentation":"Recommencer l'exposé","restart?":"Début"},help_fr:"Naviguez avec la souris, la barre d'espace, les flèches gauche/droite ou les touches Pg Up, Pg Dn. Utilisez les touches S et B pour modifier la taille de la police.",strings_hu:{slide:"oldal","help?":"segítség","contents?":"tartalom","table of contents":"tartalomjegyzék","Table of Contents":"Tartalomjegyzék","restart presentation":"bemutató újraindítása","restart?":"újraindítás"},help_hu:"Az oldalak közti lépkedéshez kattintson az egérrel, vagy használja a szóköz, a bal, vagy a jobb nyíl, illetve a Page Down, Page Up billentyűket. Az S és a B billentyűkkel változtathatja a szöveg méretét.",strings_it:{slide:"pag.","help?":"Aiuto","contents?":"Indice","table of contents":"indice","Table of Contents":"Indice","restart presentation":"Ricominciare la presentazione","restart?":"Inizio"},help_it:"Navigare con mouse, barra spazio, frecce sinistra/destra o PgUp e PgDn. Usare S e B per cambiare la dimensione dei caratteri.",strings_el:{slide:"σελίδα","help?":"βοήθεια;","contents?":"περιεχόμενα;","table of contents":"πίνακας περιεχομένων","Table of Contents":"Πίνακας Περιεχομένων","restart presentation":"επανεκκίνηση παρουσίασης","restart?":"επανεκκίνηση;"},help_el:"Πλοηγηθείτε με το κλίκ του ποντικιού, το space, τα βέλη αριστερά/δεξιά, ή Page Up και Page Down. Χρησιμοποιήστε τα πλήκτρα S και B για να αλλάξετε το μέγεθος της γραμματοσειράς.",strings_ja:{slide:"スライド","help?":"ヘルプ","contents?":"目次","table of contents":"目次を表示","Table of Contents":"目次","restart presentation":"最初から再生","restart?":"最初から"},help_ja:"マウス左クリック ・ スペース ・ 左右キー または Page Up ・ Page Downで操作, S ・ Bでフォントサイズ変更",strings_zh:{slide:"幻灯片","help?":"帮助?","contents?":"内容?","table of contents":"目录","Table of Contents":"目录","restart presentation":"重新启动展示","restart?":"重新启动?"},help_zh:"用鼠标点击, 空格条, 左右箭头, Pg Up 和 Pg Dn 导航. 用 S, B 改变字体大小.",strings_ru:{slide:"слайд","help?":"помощь?","contents?":"содержание?","table of contents":"оглавление","Table of Contents":"Оглавление","restart presentation":"перезапустить презентацию","restart?":"перезапуск?"},help_ru:"Перемещайтесь кликая мышкой, используя клавишу пробел, стрелкивлево/вправо или Pg Up и Pg Dn. Клавиши S и B меняют размер шрифта.",strings_sv:{slide:"sida","help?":"hjälp","contents?":"innehåll","table of contents":"innehållsförteckning","Table of Contents":"Innehållsförteckning","restart presentation":"visa presentationen från början","restart?":"börja om"},help_sv:"Bläddra med ett klick med vänstra musknappen, mellanslagstangenten, vänster- och högerpiltangenterna eller tangenterna Pg Up, Pg Dn. Använd tangenterna S och B för att ändra textens storlek.",strings:{},localize:function(d){if(d==""){return d}var b,c=w3c_slidy.strings[w3c_slidy.lang];if(c){b=c[d];if(b){return b}}var a=w3c_slidy.lang.split("-");if(a.length>1){c=w3c_slidy.strings[a[0]];if(c){b=c[d];if(b){return b}}}return d},init_localization:function(){var b=w3c_slidy;var a=w3c_slidy.help_text;this.strings={es:this.strings_es,ca:this.strings_ca,cs:this.strings_cs,nl:this.strings_nl,de:this.strings_de,pl:this.strings_pl,fr:this.strings_fr,hu:this.strings_hu,it:this.strings_it,el:this.strings_el,jp:this.strings_ja,zh:this.strings_zh,ru:this.strings_ru,sv:this.strings_sv},b.strings_es[a]=b.help_es;b.strings_ca[a]=b.help_ca;b.strings_cs[a]=b.help_cs;b.strings_nl[a]=b.help_nl;b.strings_de[a]=b.help_de;b.strings_pl[a]=b.help_pl;b.strings_fr[a]=b.help_fr;b.strings_hu[a]=b.help_hu;b.strings_it[a]=b.help_it;b.strings_el[a]=b.help_el;b.strings_ja[a]=b.help_ja;b.strings_zh[a]=b.help_zh;b.strings_ru[a]=b.help_ru;b.strings_sv[a]=b.help_sv;w3c_slidy.lang=document.body.parentNode.getAttribute("lang");if(!w3c_slidy.lang){w3c_slidy.lang=document.body.parentNode.getAttribute("xml:lang")}if(!w3c_slidy.lang){w3c_slidy.lang="en"}}};if(w3c_slidy.ie6||w3c_slidy.ie7){document.write("<iframe id='historyFrame' src='javascript:\"<html></html>\"' height='1' width='1' style='position:absolute;left:-800px'></iframe>")}w3c_slidy.set_up();setTimeout(w3c_slidy.hide_slides,50);
+/*]]>*/
+</script>
+</head>
+<body>
+<div class="slide titlepage">
+ <h1 class="title">Haskell Bits</h1>
+ <p class="author">
+Mark Lentczner
+ </p>
+ <p class="date">2011-09-29</p>
+</div>
+<div class="slide">
+<h1 id="haskell-is-scary">Haskell is Scary</h1>
+<ul class="incremental">
+<li>Oh noes! Where's my state?</li>
+<li>Hey, I don't want my program to be lazy!</li>
+<li>Yo, PHP doesn't need no templates or combinators...</li>
+<li>Uhm, I thought dynamic languages were better?</li>
+<li>MONADS!</li>
+</ul>
+</div>
+<div class="slide">
+<h1 id="haskell-is-scary-cool">Haskell is Scary Cool</h1>
+<ul class="incremental">
+<li>Functional</li>
+<li>Lazy</li>
+<li>Higher order Functions</li>
+<li>Static Types</li>
+<li>...shhhh: monads.</li>
+</ul>
+</div>
+<div class="slide">
+<h1 id="why-i-got-hooked">Why I got hooked</h1>
+<ul class="incremental">
+<li>It is a new way to thinking about programming</li>
+<li>It twists the brain in delightful ways.</li>
+<li>It is very expressive, yet concise and clear</li>
+<li>It is beautiful.</li>
+</ul>
+</div>
+<div class="slide">
+<h1 id="warning">Warning</h1>
+<ul class="incremental">
+<li><p>I have a lot of code to show you</p></li>
+<li><p>It's gonna look like crazy-moon language</p></li>
+<li><p>Be brave</p></li>
+</ul>
+</div>
+<div class="slide">
+<h1 id="something-familiar">Something Familiar</h1>
+<pre class="sourceCode"><code class="sourceCode bash"><span class="kw">cat</span> poem <span class="kw">|</span> <span class="kw">sort</span></code></pre>
+<pre class="sourceCode"><code class="sourceCode bash"><span class="kw">cat</span> poem <span class="kw">|</span> <span class="kw">rev</span> <span class="kw">|</span> <span class="kw">head</span></code></pre>
+<pre class="sourceCode"><code class="sourceCode bash"><span class="kw">cat</span> poem <span class="kw">|</span> <span class="kw">sed</span> -e <span class="st">'s/$/!!!/'</span></code></pre>
+</div>
+<div class="slide">
+<h1 id="what-do-they-all-do">What do they all do?</h1>
+<ul class="incremental">
+<li><p>Take input</p></li>
+<li><p>Process the input.</p></li>
+<li><p>Produce output as soon as they're able.</p></li>
+<li><p>Don't modify any state.</p></li>
+<li><p>In short, they are functional, pure, and lazy.</p></li>
+</ul>
+</div>
+<div class="slide">
+<h1 id="lets-write-that-in-haskell">Let's write that in Haskell</h1>
+<pre class="sourceCode"><code class="sourceCode haskell">main <span class="fu">=</span> <span class="fu">readFile</span> <span class="st">&quot;poem&quot;</span> <span class="fu">&gt;&gt;=</span> <span class="fu">putStr</span> <span class="fu">.</span> process<br /><br />process t <span class="fu">=</span> <span class="fu">unlines</span> (<span class="fu">sort</span> (<span class="fu">lines</span> t))</code></pre>
+<p>Put that in a file named <code>Part.hs</code> and then at the shell:</p>
+<pre class="sourceCode"><code class="sourceCode bash">runhaskell Part1.hs</code></pre>
+</div>
+<div class="slide">
+<h1 id="ignoring-the-main-behind-the-curtain...">Ignoring the main behind the curtain...</h1>
+<pre class="sourceCode"><code class="sourceCode haskell">process t <span class="fu">=</span> <span class="fu">unlines</span> (<span class="fu">sort</span> (<span class="fu">lines</span> t))</code></pre>
+<p>Remember <strong>f(g(x)) = (f⋅g)(x)</strong> from high school algebra?</p>
+<pre class="sourceCode"><code class="sourceCode haskell">process' t <span class="fu">=</span> (<span class="fu">unlines</span> <span class="fu">.</span> <span class="fu">sort</span> <span class="fu">.</span> <span class="fu">lines</span>) t</code></pre>
+<p>And algebraic simplificiation works here too:</p>
+<pre class="sourceCode"><code class="sourceCode haskell">process'' <span class="fu">=</span> <span class="fu">unlines</span> <span class="fu">.</span> <span class="fu">sort</span> <span class="fu">.</span> <span class="fu">lines</span></code></pre>
+</div>
+<div class="slide">
+<h1 id="we-could-code-some-other-common-ones">We could code some other common ones:</h1>
+<pre class="sourceCode"><code class="sourceCode haskell">sortLines <span class="fu">=</span> <span class="fu">unlines</span> <span class="fu">.</span> <span class="fu">sort</span> <span class="fu">.</span> <span class="fu">lines</span><br />reverseLines <span class="fu">=</span> <span class="fu">unlines</span> <span class="fu">.</span> <span class="fu">reverse</span> <span class="fu">.</span> <span class="fu">lines</span><br />firstTwoLines <span class="fu">=</span> <span class="fu">unlines</span> <span class="fu">.</span> <span class="fu">take</span> <span class="dv">2</span> <span class="fu">.</span> <span class="fu">lines</span></code></pre>
+<p>Anyone spot a pattern?</p>
+</div>
+<div class="slide">
+<h1 id="we-can-factor-it-out">We can factor it out!</h1>
+<pre class="sourceCode"><code class="sourceCode haskell">byLines f <span class="fu">=</span> <span class="fu">unlines</span> <span class="fu">.</span> f <span class="fu">.</span> <span class="fu">lines</span><br /><br />sortLines' <span class="fu">=</span> byLines <span class="fu">sort</span><br />reverseLines' <span class="fu">=</span> byLines <span class="fu">reverse</span><br />firstTwoLines' <span class="fu">=</span> byLines (<span class="fu">take</span> <span class="dv">2</span>)</code></pre>
+</div>
+<div class="slide">
+<h1 id="what-if-we-want-to-modify-the-lines">What if we want to modify the lines?</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">indent </span><span class="ot">::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span><br />indent s <span class="fu">=</span> <span class="st">&quot; &quot;</span> <span class="fu">++</span> s</code></pre>
+<p>and then, obviously:</p>
+<pre class="sourceCode"><code class="sourceCode haskell">indentLines <span class="fu">=</span> byLines indent</code></pre>
+</div>
+<div class="slide">
+<h1 id="boom">BOOM!</h1>
+<pre class="sourceCode"><code class="sourceCode haskell">indentLines <span class="fu">=</span> byLines indent</code></pre>
+<p>doesn't compile:</p>
+<pre><code> Couldn't match expected type `[Char]' with actual type `Char'
+ Expected type: [String] -&gt; [String]
+ Actual type: String -&gt; String
+ In the first argument of `byLines', namely `indent'
+ In the expression: byLines indent
+</code></pre>
+</div>
+<div class="slide">
+<h1 id="map-to-the-rescue"><code>map</code> to the rescue:</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">map</span><span class="ot"> </span><span class="ot">::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [b]</code></pre>
+<p>as in:</p>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">map</span> <span class="fu">reverse</span> [<span class="st">&quot;red&quot;</span>, <span class="st">&quot;yellow&quot;</span>, <span class="st">&quot;blue&quot;</span>]<br />[<span class="st">&quot;der&quot;</span>,<span class="st">&quot;wolley&quot;</span>,<span class="st">&quot;eulb&quot;</span>]<br /><br /><span class="fu">map</span> <span class="fu">sort</span> [<span class="st">&quot;red&quot;</span>, <span class="st">&quot;yellow&quot;</span>, <span class="st">&quot;blue&quot;</span>]<br />[<span class="st">&quot;der&quot;</span>,<span class="st">&quot;ellowy&quot;</span>,<span class="st">&quot;belu&quot;</span>]</code></pre>
+<p>compare:</p>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">reverse</span> [<span class="st">&quot;red&quot;</span>, <span class="st">&quot;yellow&quot;</span>, <span class="st">&quot;blue&quot;</span>]<br />[<span class="st">&quot;blue&quot;</span>,<span class="st">&quot;yellow&quot;</span>,<span class="st">&quot;red&quot;</span>]<br /><br /><span class="fu">sort</span> [<span class="st">&quot;red&quot;</span>, <span class="st">&quot;yellow&quot;</span>, <span class="st">&quot;blue&quot;</span>]<br />[<span class="st">&quot;blue&quot;</span>,<span class="st">&quot;red&quot;</span>,<span class="st">&quot;yellow&quot;</span>]</code></pre>
+</div>
+<div class="slide">
+<h1 id="so-then">So then:</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">indentEachLine </span><span class="ot">::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span><br />indentEachLine <span class="fu">=</span> byLines (<span class="fu">map</span> indent)<br /><br /><span class="ot">eachLine </span><span class="ot">::</span> (<span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span>) <span class="ot">-&gt;</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span><br />eachLine f <span class="fu">=</span> <span class="fu">unlines</span> <span class="fu">.</span> <span class="fu">map</span> f <span class="fu">.</span> <span class="fu">lines</span><br /><br /><span class="ot">indentEachLine' </span><span class="ot">::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span><br />indentEachLine' <span class="fu">=</span> eachLine indent</code></pre>
+</div>
+<div class="slide">
+<h1 id="but-wait-wheres-the-second-argument-to-map">But wait, where's the second argument to <code>map</code>?</h1>
+<p>Think of <code>map</code>s type this way:</p>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">map</span><span class="ot"> </span><span class="ot">::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> ([a] <span class="ot">-&gt;</span> [b])</code></pre>
+<p>It takes a function and transforms (lifts) it into a function over lists</p>
+</div>
+<div class="slide">
+<h1 id="lets-yell">Let's *YELL!*</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">yell </span><span class="ot">::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span><br />yell s <span class="fu">=</span> <span class="fu">map</span> <span class="fu">toUpper</span> s <span class="fu">++</span> <span class="st">&quot;!!!&quot;</span><br /><br /><span class="ot">yellEachLine </span><span class="ot">::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span><br />yellEachLine <span class="fu">=</span> eachLine yell</code></pre>
+</div>
+<div class="slide">
+<h1 id="what-if-we-wanted-it-by-words">What if we wanted it by words?</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">eachWord </span><span class="ot">::</span> (<span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span>) <span class="ot">-&gt;</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span><br />eachWord f <span class="fu">=</span> <span class="fu">unwords</span> <span class="fu">.</span> <span class="fu">map</span> f <span class="fu">.</span> <span class="fu">words</span><br /><br /><span class="ot">yellEachWord </span><span class="ot">::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span><br />yellEachWord <span class="fu">=</span> eachWord yell</code></pre>
+<p><em>d'oh!</em></p>
+</div>
+<div class="slide">
+<h1 id="we-want-by-words-by-lines...">We want by words, by lines...</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">eachWordOnEachLine </span><span class="ot">::</span> (<span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span>) <span class="ot">-&gt;</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span><br />eachWordOnEachLine f <span class="fu">=</span> eachLine (eachWord f)<br /><br /><span class="ot">yellEachWordOnEachLine </span><span class="ot">::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span><br />yellEachWordOnEachLine <span class="fu">=</span> eachWord' yell</code></pre>
+</div>
+<div class="slide">
+<h1 id="what-bus-hit-us">What bus hit us?</h1>
+<p>Higher Order Functions</p>
+</div>
+<div class="slide">
+<p>(Pause to catch breath)</p>
+</div>
+<div class="slide">
+<p><em>Onward!</em></p>
+</div>
+<div class="slide">
+<h1 id="structured-data">Structured data</h1>
+<p>By which I mean lists, of course...</p>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">List</span> &#945; <span class="fu">=</span> <span class="dt">Nil</span><br /> <span class="fu">|</span> <span class="dt">Cons</span> &#945; (<span class="dt">List</span> &#945;)</code></pre>
+<p>we can make some values of this type:</p>
+<pre class="sourceCode"><code class="sourceCode haskell">empty <span class="fu">=</span> <span class="dt">Nil</span><br />oneWord <span class="fu">=</span> <span class="dt">Cons</span> <span class="st">&quot;apple&quot;</span> <span class="dt">Nil</span><br />twoWords <span class="fu">=</span> <span class="dt">Cons</span> <span class="st">&quot;banana&quot;</span> (<span class="dt">Cons</span> <span class="st">&quot;cantaloupe&quot;</span> <span class="dt">Nil</span>)</code></pre>
+</div>
+<div class="slide">
+<h1 id="pop-quiz">Pop quiz</h1>
+<p>Given these..</p>
+<pre class="sourceCode"><code class="sourceCode haskell">empty <span class="fu">=</span> <span class="dt">Nil</span><br />oneWord <span class="fu">=</span> <span class="dt">Cons</span> <span class="st">&quot;apple&quot;</span> <span class="dt">Nil</span><br />twoWords <span class="fu">=</span> <span class="dt">Cons</span> <span class="st">&quot;banana&quot;</span> (<span class="dt">Cons</span> <span class="st">&quot;cantaloupe&quot;</span> <span class="dt">Nil</span>)</code></pre>
+<p>What are these?</p>
+<pre class="sourceCode"><code class="sourceCode haskell">mystery1 <span class="fu">=</span> <span class="dt">Cons</span> <span class="st">&quot;pear&quot;</span> empty<br />mystery2 <span class="fu">=</span> <span class="dt">Cons</span> <span class="st">&quot;peach&quot;</span> oneWord<br />mystery3 <span class="fu">=</span> <span class="dt">Cons</span> <span class="st">&quot;pineapple&quot;</span> mystery3<br />mystery4 <span class="fu">=</span> <span class="dt">Cons</span> <span class="dv">42</span> (<span class="dt">Cons</span> <span class="st">&quot;apple&quot;</span> <span class="dt">Nil</span>)</code></pre>
+</div>
+<div class="slide">
+<h1 id="some-functions-on-list">Some functions on List</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">dropOne </span><span class="ot">::</span> <span class="dt">List</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> a<br />dropOne (<span class="dt">Cons</span> first rest) <span class="fu">=</span> rest<br />dropOne <span class="dt">Nil</span> <span class="fu">=</span> <span class="dt">Nil</span><br /><br /><span class="ot">justOne </span><span class="ot">::</span> <span class="dt">List</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> a<br />justOne (<span class="dt">Cons</span> a _) <span class="fu">=</span> <span class="dt">Cons</span> a <span class="dt">Nil</span><br />justOne <span class="dt">Nil</span> <span class="fu">=</span> <span class="dt">Nil</span></code></pre>
+</div>
+<div class="slide">
+<h1 id="a-bad-function">A bad function</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">firstOne </span><span class="ot">::</span> <span class="dt">List</span> a <span class="ot">-&gt;</span> a<br />firstOne (<span class="dt">Cons</span> a _) <span class="fu">=</span> a<br />firstOne <span class="dt">Nil</span> <span class="fu">=</span> <span class="fu">error</span> <span class="st">&quot;O Noes!&quot;</span></code></pre>
+</div>
+<div class="slide">
+<h1 id="maybe-a-better-way">Maybe a better way</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">maybeFirstOne </span><span class="ot">::</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> a <span class="ot">-&gt;</span> a<br />maybeFirstOne def (<span class="dt">Cons</span> first rest) <span class="fu">=</span> first<br />maybeFirstOne def <span class="dt">Nil</span> <span class="fu">=</span> def</code></pre>
+</div>
+<div class="slide">
+<h1 id="actually-we-dont-type-so-much">Actually, we don't type so much</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> [a] <span class="fu">=</span> [] <span class="fu">|</span> a <span class="fu">:</span> [a] <span class="co">-- this is built in</span><br /><span class="kw">infixr</span> <span class="dv">5</span> <span class="fu">:</span><br /><br />empty <span class="fu">=</span> []<br />oneWord <span class="fu">=</span> <span class="st">&quot;apple&quot;</span> <span class="fu">:</span> []<br />twoWords <span class="fu">=</span> <span class="st">&quot;banana&quot;</span> <span class="fu">:</span> <span class="st">&quot;cantaloupe&quot;</span> <span class="fu">:</span> []<br /><br />mystery1 <span class="fu">=</span> <span class="st">&quot;pear&quot;</span> <span class="fu">:</span> empty<br />mystery2 <span class="fu">=</span> <span class="st">&quot;peach&quot;</span> <span class="fu">:</span> oneWord<br />mystery3 <span class="fu">=</span> <span class="st">&quot;pineapple&quot;</span> <span class="fu">:</span> mystery3<br />mystery4 <span class="fu">=</span> <span class="dv">42</span> <span class="fu">:</span> <span class="st">&quot;apple&quot;</span> <span class="fu">:</span> []<br /><br /><span class="ot">dropOne </span><span class="ot">::</span> [a] <span class="ot">-&gt;</span> [a]<br />dropOne (first<span class="fu">:</span>rest) <span class="fu">=</span> rest<br />dropOne [] <span class="fu">=</span> []<br /><br /><span class="ot">justOne </span><span class="ot">::</span> [a] <span class="ot">-&gt;</span> [a]<br />justOne (a<span class="fu">:</span>_) <span class="fu">=</span> a<span class="fu">:</span>[]<br />justOne [] <span class="fu">=</span> []<br /><br /><span class="ot">firstOne </span><span class="ot">::</span> [a] <span class="ot">-&gt;</span> a<br />firstOne (a<span class="fu">:</span>_) <span class="fu">=</span> a<br />firstOne [] <span class="fu">=</span> <span class="fu">error</span> <span class="st">&quot;O Noes!&quot;</span><br /><br /><span class="ot">maybeFirstOne </span><span class="ot">::</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> a<br />maybeFirstOne def (first<span class="fu">:</span>rest) <span class="fu">=</span> first<br />maybeFirstOne def [] <span class="fu">=</span> def</code></pre>
+</div>
+<div class="slide">
+<h1 id="actually-not-even-that-much">Actually, not even that much</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> [a] <span class="fu">=</span> [] <span class="fu">|</span> a <span class="fu">:</span> [a] <span class="co">-- this is built in</span><br /><span class="kw">infixr</span> <span class="dv">5</span> <span class="fu">:</span><br /><br />empty <span class="fu">=</span> []<br />oneWord <span class="fu">=</span> [<span class="st">&quot;apple&quot;</span>] <span class="co">-- syntatic sugar</span><br />twoWords <span class="fu">=</span> [<span class="st">&quot;banana&quot;</span>, <span class="st">&quot;cantaloupe&quot;</span>] <span class="co">-- two teaspoons full</span><br /><br />mystery1 <span class="fu">=</span> <span class="st">&quot;pear&quot;</span> <span class="fu">:</span> empty<br />mystery2 <span class="fu">=</span> <span class="st">&quot;peach&quot;</span> <span class="fu">:</span> oneWord<br />mystery3 <span class="fu">=</span> <span class="st">&quot;pineapple&quot;</span> <span class="fu">:</span> mystery3<br />mystery4 <span class="fu">=</span> [<span class="dv">42</span>, <span class="st">&quot;apple&quot;</span>] <span class="co">-- sweet, but still won't compile</span><br /><br /><span class="ot">dropOne </span><span class="ot">::</span> [a] <span class="ot">-&gt;</span> [a]<br />dropOne (first<span class="fu">:</span>rest) <span class="fu">=</span> rest<br />dropOne [] <span class="fu">=</span> []<br /><br /><span class="ot">justOne </span><span class="ot">::</span> [a] <span class="ot">-&gt;</span> [a] <span class="co">-- don't confuse these &quot;[a]&quot;s</span><br />justOne (a<span class="fu">:</span>_) <span class="fu">=</span> [a] <span class="co">-- with this &quot;[a]&quot;</span><br />justOne [] <span class="fu">=</span> []<br /><br /><span class="ot">firstOne </span><span class="ot">::</span> [a] <span class="ot">-&gt;</span> a <span class="co">-- normally called 'head'</span><br />firstOne (a<span class="fu">:</span>_) <span class="fu">=</span> a<br />firstOne [] <span class="fu">=</span> <span class="fu">error</span> <span class="st">&quot;O Noes!&quot;</span><br /><br /><span class="ot">maybeFirstOne </span><span class="ot">::</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> a<br />maybeFirstOne def (first<span class="fu">:</span>rest) <span class="fu">=</span> first<br />maybeFirstOne def [] <span class="fu">=</span> def</code></pre>
+</div>
+<div class="slide">
+<h1 id="the-type-that-blew-my-mind">The type that blew my mind:</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">Maybe</span> a <span class="fu">=</span> <span class="kw">Nothing</span> <span class="fu">|</span> <span class="kw">Just</span> a</code></pre>
+<p>Let's us write this better:</p>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">firstOne' </span><span class="ot">::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a<br />firstOne' (a<span class="fu">:</span>_) <span class="fu">=</span> <span class="kw">Just</span> a<br />firstOne' [] <span class="fu">=</span> <span class="kw">Nothing</span></code></pre>
+</div>
+<div class="slide">
+<h1 id="why-is-this-useful">Why is this useful?</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">elemIndex </span><span class="ot">::</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Int</span><br /><br /><span class="fu">lookup</span><span class="ot"> </span><span class="ot">::</span> k <span class="ot">-&gt;</span> <span class="dt">Map</span> k a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a<br /><br /><span class="ot">stripPrefix </span><span class="ot">::</span> <span class="dt">Text</span> <span class="ot">-&gt;</span> <span class="dt">Text</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Text</span><br /><br /><span class="ot">port </span><span class="ot">::</span> <span class="dt">URIAuthority</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Int</span></code></pre>
+</div>
+<div class="slide">
+<h1 id="one-more-built-in-thing">One more built-in thing:</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">type</span> <span class="dt">String</span> <span class="fu">=</span> [<span class="dt">Char</span>]</code></pre>
+</div>
+<div class="slide">
+<h1 id="now-lets-write-some-real-code">Now, let's write some real code</h1>
+<p>Find the first character after a star:</p>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">findAfterStar </span><span class="ot">::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Char</span><br />findAfterStar (c<span class="fu">:</span>d<span class="fu">:</span>r) <span class="fu">=</span><br /> <span class="kw">if</span> c <span class="fu">==</span> <span class="ch">'*'</span> <span class="kw">then</span> <span class="kw">Just</span> d<br /> <span class="kw">else</span> findAfterStar (d<span class="fu">:</span>r)<br />findAfterStar _ <span class="fu">=</span> <span class="kw">Nothing</span></code></pre>
+</div>
+<div class="slide">
+<h1 id="make-it-a-little-be-more-generic">Make it a little be more generic</h1>
+<p>Find the first character after some other character:</p>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">findAfterChar </span><span class="ot">::</span> <span class="dt">Char</span> <span class="ot">-&gt;</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Char</span><br />findAfterChar m (c<span class="fu">:</span>d<span class="fu">:</span>r) <span class="fu">=</span><br /> <span class="kw">if</span> c <span class="fu">==</span> m <span class="kw">then</span> <span class="kw">Just</span> d<br /> <span class="kw">else</span> findAfterChar m (d<span class="fu">:</span>r)<br />findAfterChar _ _ <span class="fu">=</span> <span class="kw">Nothing</span></code></pre>
+</div>
+<div class="slide">
+<h1 id="more-generic-still">More generic still</h1>
+<p>Find the first thing after some other thing:</p>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">findAfterElem </span><span class="ot">::</span> <span class="kw">Eq</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a<br />findAfterElem m (c<span class="fu">:</span>d<span class="fu">:</span>r) <span class="fu">=</span><br /> <span class="kw">if</span> c <span class="fu">==</span> m <span class="kw">then</span> <span class="kw">Just</span> d<br /> <span class="kw">else</span> findAfterElem m (d<span class="fu">:</span>r)<br />findAfterElem _ _ <span class="fu">=</span> <span class="kw">Nothing</span></code></pre>
+</div>
+<div class="slide">
+<p>(Pause to catch breath)</p>
+</div>
+<div class="slide">
+<p><em>Onward!</em></p>
+</div>
+<div class="slide">
+<h1 id="types-you-dont-type">Types you don't type</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">runLengthEncode </span><span class="ot">::</span> <span class="kw">Eq</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [(a, <span class="dt">Int</span>)]<br />runLengthEncode [] <span class="fu">=</span> []<br />runLengthEncode (x<span class="fu">:</span>xs) <span class="fu">=</span> nextGroup x <span class="dv">1</span> xs <br /> <span class="kw">where</span><br /> nextGroup e n [] <span class="fu">=</span> [(e, n)]<br /> nextGroup e n (y<span class="fu">:</span>ys)<br /> <span class="fu">|</span> e <span class="fu">==</span> y <span class="fu">=</span> nextGroup e (n <span class="fu">+</span> <span class="dv">1</span>) ys<br /> <span class="fu">|</span> <span class="fu">otherwise</span> <span class="fu">=</span> (e, n) <span class="fu">:</span> nextGroup y <span class="dv">1</span> ys</code></pre>
+</div>
+<div class="slide">
+<h1 id="lets-try-that-in-c">Let's try that in C++</h1>
+<pre class="sourceCode"><code class="sourceCode cpp"><span class="kw">template</span>&lt;<span class="kw">typename</span> T&gt;<br />list&lt;pair&lt;T,<span class="dt">int</span>&gt; &gt; runLengthEncode(<span class="dt">const</span> list&lt;T&gt;&amp; as) {<br /> list&lt;pair&lt;T, <span class="dt">int</span>&gt; &gt; runs;<br /> <span class="kw">if</span> (!empty(as)) {<br /> list&lt;T&gt;::const_iterator it = as.begin();<br /> T elem = *it;<br /> <span class="dt">int</span> count = <span class="dv">0</span>;<br /><br /> <span class="kw">for</span> (; it != as.end(); it++) {<br /> <span class="kw">if</span> (elem != *it) {<br /> runs.push_back(make_pair(elem, count));<br /> elem = *it;<br /> count = <span class="dv">0</span>;<br /> }<br /> count += <span class="dv">1</span>;<br /> }<br /> runs.push_back(make_pair(elem, count));<br /> }<br /> <span class="kw">return</span> runs;<br />}</code></pre>
+</div>
+<div class="slide">
+<h1 id="quick-check">Quick Check</h1>
+<p>Just write some properties that should hold:</p>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="ot">rlePropLengthPreserved </span><span class="ot">::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Bool</span><br />rlePropLengthPreserved <span class="kw">as</span> <span class="fu">=</span> <span class="fu">length</span> <span class="kw">as</span> <span class="fu">==</span> (<span class="fu">sum</span> <span class="fu">$</span> <span class="fu">map</span> <span class="fu">snd</span> <span class="fu">$</span> runLengthEncode <span class="kw">as</span>)<br /><br /><span class="ot">rlePropDupesCollapsed </span><span class="ot">::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span><br />rlePropDupesCollapsed n<br /> <span class="fu">|</span> m <span class="fu">==</span> <span class="dv">0</span> <span class="fu">=</span> runLengthEncode <span class="st">&quot;&quot;</span> <span class="fu">==</span> []<br /> <span class="fu">|</span> <span class="fu">otherwise</span> <span class="fu">=</span> runLengthEncode (<span class="fu">replicate</span> m <span class="ch">'x'</span>) <span class="fu">==</span> [(<span class="ch">'x'</span>, m)]<br /> <span class="kw">where</span> m <span class="fu">=</span> n <span class="ot">`mod`</span> <span class="dv">100</span><br /><br /><span class="ot">rlePropRoundTrip </span><span class="ot">::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Bool</span><br />rlePropRoundTrip ns <span class="fu">=</span> runLengthEncode xs <span class="fu">==</span> is<br /> <span class="kw">where</span> is <span class="fu">=</span> <span class="fu">zip</span> [<span class="ch">'a'</span><span class="fu">..</span>] <span class="fu">$</span> <span class="fu">map</span> (\n <span class="ot">-&gt;</span> n <span class="ot">`mod`</span> <span class="dv">100</span> <span class="fu">+</span> <span class="dv">1</span>) ns<br /> xs <span class="fu">=</span> <span class="fu">concatMap</span> (\(i,n) <span class="ot">-&gt;</span> <span class="fu">replicate</span> n i) is</code></pre>
+</div>
+<div class="slide">
+<h1 id="quick-check-em">Quick Check 'em:</h1>
+<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">&gt;</span> quickCheck rlePropRoundTrip <br /><span class="fu">+++</span> <span class="dt">OK</span>, passed <span class="dv">100</span> tests<span class="fu">.</span><br /><span class="fu">&gt;</span> quickCheck rlePropDupesCollapsed <br /><span class="fu">+++</span> <span class="dt">OK</span>, passed <span class="dv">100</span> tests<span class="fu">.</span><br /><span class="fu">&gt;</span> quickCheck rlePropRoundTrip <br /><span class="fu">+++</span> <span class="dt">OK</span>, passed <span class="dv">100</span> tests<span class="fu">.</span></code></pre>
+</div>
+<div class="slide">
+<p>Whew</p>
+</div>
+<div class="slide">
+<h1 id="oh-and-some-more-things">Oh, and some more things:</h1>
+<ul class="incremental">
+<li>ghci</li>
+<li>cabal &amp; hackage</li>
+<li>haddock</li>
+<li>Hoogle</li>
+<li><code>#haskell</code> on <code>irc.freenode.org</code></li>
+</ul>
+</div>
+<div class="slide">
+<h1 id="thanks">Thanks</h1>
+<p>Mark Lentczner</p>
+<p><code>mark@glyphic.com</code></p>
+<p><code>mzero</code> on IRC</p>
+</div>
+</body>
+</html>
530 slides.md
@@ -0,0 +1,530 @@
+% Haskell Bits
+% Mark Lentczner
+% 2011-09-29
+
+# Haskell is Scary
+
+* Oh noes! Where's my state?
+* Hey, I don't want my program to be lazy!
+* Yo, PHP doesn't need no templates or combinators...
+* Uhm, I thought dynamic languages were better?
+* MONADS!
+
+# Haskell is Scary Cool
+
+* Functional
+* Lazy
+* Higher order Functions
+* Static Types
+* ...shhhh: monads.
+
+# Why I got hooked
+
+* It is a new way to thinking about programming
+* It twists the brain in delightful ways.
+* It is very expressive, yet concise and clear
+* It is beautiful.
+
+# Warning
+
+* I have a lot of code to show you
+
+* It's gonna look like crazy-moon language
+
+* Be brave
+
+
+# Something Familiar
+
+~~~~ {.bash}
+cat poem | sort
+~~~~
+
+~~~~ {.bash}
+cat poem | rev | head
+~~~~
+
+~~~~ {.bash}
+cat poem | sed -e 's/$/!!!/'
+~~~~
+
+# What do they all do?
+
+* Take input
+
+* Process the input.
+
+* Produce output as soon as they're able.
+
+* Don't modify any state.
+
+* In short, they are functional, pure, and lazy.
+
+# Let's write that in Haskell
+
+~~~~ {.haskell}
+main = readFile "poem" >>= putStr . process
+
+process t = unlines (sort (lines t))
+~~~~
+
+Put that in a file named `Part.hs` and then at the shell:
+
+~~~~ {.bash}
+runhaskell Part1.hs
+~~~~
+
+# Ignoring the main behind the curtain...
+
+~~~~ {.haskell}
+process t = unlines (sort (lines t))
+~~~~
+
+Remember **f(g(x)) = (f⋅g)(x)** from high school algebra?
+
+~~~~ {.haskell}
+process' t = (unlines . sort . lines) t
+~~~~
+
+And algebraic simplificiation works here too:
+
+~~~~ {.haskell}
+process'' = unlines . sort . lines
+~~~~
+
+# We could code some other common ones:
+
+~~~~ {.haskell}
+sortLines = unlines . sort . lines
+reverseLines = unlines . reverse . lines
+firstTwoLines = unlines . take 2 . lines
+~~~~
+
+Anyone spot a pattern?
+
+# We can factor it out!
+
+~~~~ {.haskell}
+byLines f = unlines . f . lines
+
+sortLines' = byLines sort
+reverseLines' = byLines reverse
+firstTwoLines' = byLines (take 2)
+~~~~
+
+# What if we want to modify the lines?
+
+~~~~ {.haskell}
+indent :: String -> String
+indent s = " " ++ s
+~~~~
+
+and then, obviously:
+
+~~~~ {.haskell}
+indentLines = byLines indent
+~~~~
+
+# BOOM!
+
+~~~~ {.haskell}
+indentLines = byLines indent
+~~~~
+
+doesn't compile:
+
+~~~~
+ Couldn't match expected type `[Char]' with actual type `Char'
+ Expected type: [String] -> [String]
+ Actual type: String -> String
+ In the first argument of `byLines', namely `indent'
+ In the expression: byLines indent
+~~~~
+
+# `map` to the rescue:
+
+~~~~ {.haskell}
+map :: (a -> b) -> [a] -> [b]
+~~~~
+
+as in:
+
+~~~~ {.haskell}
+map reverse ["red", "yellow", "blue"]
+["der","wolley","eulb"]
+
+map sort ["red", "yellow", "blue"]
+["der","ellowy","belu"]
+~~~~
+
+compare:
+
+~~~~ {.haskell}
+reverse ["red", "yellow", "blue"]
+["blue","yellow","red"]
+
+sort ["red", "yellow", "blue"]
+["blue","red","yellow"]
+~~~~
+
+# So then:
+
+~~~~ {.haskell}
+indentEachLine :: String -> String
+indentEachLine = byLines (map indent)
+
+eachLine :: (String -> String) -> String -> String
+eachLine f = unlines . map f . lines
+
+indentEachLine' :: String -> String
+indentEachLine' = eachLine indent
+~~~~
+
+# But wait, where's the second argument to `map`?
+
+Think of `map`s type this way:
+
+~~~~ {.haskell}
+map :: (a -> b) -> ([a] -> [b])
+~~~~
+
+It takes a function and transforms (lifts) it into a function over lists
+
+# Let's \*YELL!\*
+
+~~~~ {.haskell}
+yell :: String -> String
+yell s = map toUpper s ++ "!!!"
+
+yellEachLine :: String -> String
+yellEachLine = eachLine yell
+~~~~
+
+# What if we wanted it by words?
+
+~~~~ {.haskell}
+eachWord :: (String -> String) -> String -> String
+eachWord f = unwords . map f . words
+
+yellEachWord :: String -> String
+yellEachWord = eachWord yell
+~~~~
+
+*d'oh!*
+
+# We want by words, by lines...
+
+~~~~ {.haskell}
+eachWordOnEachLine :: (String -> String) -> String -> String
+eachWordOnEachLine f = eachLine (eachWord f)
+
+yellEachWordOnEachLine :: String -> String
+yellEachWordOnEachLine = eachWord' yell
+~~~~
+
+
+# What bus hit us?
+
+Higher Order Functions
+
+----
+
+(Pause to catch breath)
+
+----
+
+*Onward!*
+
+#Structured data
+
+By which I mean lists, of course...
+
+~~~~ {.haskell}
+data List α = Nil
+ | Cons α (List α)
+~~~~
+
+we can make some values of this type:
+
+~~~~ {.haskell}
+empty = Nil
+oneWord = Cons "apple" Nil
+twoWords = Cons "banana" (Cons "cantaloupe" Nil)
+~~~~
+
+# Pop quiz
+
+Given these..
+
+~~~~ {.haskell}
+empty = Nil
+oneWord = Cons "apple" Nil
+twoWords = Cons "banana" (Cons "cantaloupe" Nil)
+~~~~
+
+What are these?
+
+~~~~ {.haskell}
+mystery1 = Cons "pear" empty
+mystery2 = Cons "peach" oneWord
+mystery3 = Cons "pineapple" mystery3
+mystery4 = Cons 42 (Cons "apple" Nil)
+~~~~
+
+# Some functions on List
+
+~~~~ {.haskell}
+dropOne :: List a -> List a
+dropOne (Cons first rest) = rest
+dropOne Nil = Nil
+
+justOne :: List a -> List a
+justOne (Cons a _) = Cons a Nil
+justOne Nil = Nil
+~~~~
+
+# A bad function
+
+~~~~ {.haskell}
+firstOne :: List a -> a
+firstOne (Cons a _) = a
+firstOne Nil = error "O Noes!"
+~~~~
+
+# Maybe a better way
+
+~~~~ {.haskell}
+maybeFirstOne :: a -> List a -> a
+maybeFirstOne def (Cons first rest) = first
+maybeFirstOne def Nil = def
+~~~~
+
+# Actually, we don't type so much
+
+~~~~ {.haskell}
+data [a] = [] | a : [a] -- this is built in
+infixr 5 :
+
+empty = []
+oneWord = "apple" : []
+twoWords = "banana" : "cantaloupe" : []
+
+mystery1 = "pear" : empty
+mystery2 = "peach" : oneWord
+mystery3 = "pineapple" : mystery3
+mystery4 = 42 : "apple" : []
+
+dropOne :: [a] -> [a]
+dropOne (first:rest) = rest
+dropOne [] = []
+
+justOne :: [a] -> [a]
+justOne (a:_) = a:[]
+justOne [] = []
+
+firstOne :: [a] -> a
+firstOne (a:_) = a
+firstOne [] = error "O Noes!"
+
+maybeFirstOne :: a -> [a] -> a
+maybeFirstOne def (first:rest) = first
+maybeFirstOne def [] = def
+~~~~
+
+# Actually, not even that much
+
+~~~~ {.haskell}
+data [a] = [] | a : [a] -- this is built in
+infixr 5 :
+
+empty = []
+oneWord = ["apple"] -- syntatic sugar
+twoWords = ["banana", "cantaloupe"] -- two teaspoons full
+
+mystery1 = "pear" : empty
+mystery2 = "peach" : oneWord
+mystery3 = "pineapple" : mystery3
+mystery4 = [42, "apple"] -- sweet, but still won't compile
+
+dropOne :: [a] -> [a]
+dropOne (first:rest) = rest
+dropOne [] = []
+
+justOne :: [a] -> [a] -- don't confuse these "[a]"s
+justOne (a:_) = [a] -- with this "[a]"
+justOne [] = []
+
+firstOne :: [a] -> a -- normally called 'head'
+firstOne (a:_) = a
+firstOne [] = error "O Noes!"
+
+maybeFirstOne :: a -> [a] -> a
+maybeFirstOne def (first:rest) = first
+maybeFirstOne def [] = def
+~~~~
+
+# The type that blew my mind:
+
+~~~~ {.haskell}
+data Maybe a = Nothing | Just a
+~~~~
+
+Let's us write this better:
+
+~~~~ {.haskell}
+firstOne' :: [a] -> Maybe a
+firstOne' (a:_) = Just a
+firstOne' [] = Nothing
+~~~~
+
+# Why is this useful?
+
+~~~~ {.haskell}
+elemIndex :: a -> [a] -> Maybe Int
+
+lookup :: k -> Map k a -> Maybe a
+
+stripPrefix :: Text -> Text -> Maybe Text
+
+port :: URIAuthority -> Maybe Int
+~~~~
+
+# One more built-in thing:
+
+~~~~ {.haskell}
+type String = [Char]
+~~~~
+
+# Now, let's write some real code
+
+Find the first character after a star:
+
+~~~~ {.haskell}
+findAfterStar :: String -> Maybe Char
+findAfterStar (c:d:r) =
+ if c == '*' then Just d
+ else findAfterStar (d:r)
+findAfterStar _ = Nothing
+~~~~
+
+# Make it a little be more generic
+
+Find the first character after some other character:
+
+~~~~ {.haskell}
+findAfterChar :: Char -> String -> Maybe Char
+findAfterChar m (c:d:r) =
+ if c == m then Just d
+ else findAfterChar m (d:r)
+findAfterChar _ _ = Nothing
+~~~~
+
+# More generic still
+
+Find the first thing after some other thing:
+
+~~~~ {.haskell}
+findAfterElem :: Eq a => a -> [a] -> Maybe a
+findAfterElem m (c:d:r) =
+ if c == m then Just d
+ else findAfterElem m (d:r)
+findAfterElem _ _ = Nothing
+~~~~
+
+----
+
+(Pause to catch breath)
+
+----
+
+*Onward!*
+
+# Types you don't type
+
+~~~~ {.haskell}
+runLengthEncode :: Eq a => [a] -> [(a, Int)]
+runLengthEncode [] = []
+runLengthEncode (x:xs) = nextGroup x 1 xs
+ where
+ nextGroup e n [] = [(e, n)]
+ nextGroup e n (y:ys)
+ | e == y = nextGroup e (n + 1) ys
+ | otherwise = (e, n) : nextGroup y 1 ys
+~~~~
+
+# Let's try that in C++
+
+~~~~ {.cpp}
+template<typename T>
+list<pair<T,int> > runLengthEncode(const list<T>& as) {
+ list<pair<T, int> > runs;
+ if (!empty(as)) {
+ list<T>::const_iterator it = as.begin();
+ T elem = *it;
+ int count = 0;
+
+ for (; it != as.end(); it++) {
+ if (elem != *it) {
+ runs.push_back(make_pair(elem, count));
+ elem = *it;
+ count = 0;
+ }
+ count += 1;
+ }
+ runs.push_back(make_pair(elem, count));
+ }
+ return runs;
+}
+~~~~
+
+# Quick Check
+
+Just write some properties that should hold:
+
+~~~~ {.haskell}
+rlePropLengthPreserved :: [Int] -> Bool
+rlePropLengthPreserved as = length as == (sum $ map snd $ runLengthEncode as)
+
+rlePropDupesCollapsed :: Int -> Bool
+rlePropDupesCollapsed n
+ | m == 0 = runLengthEncode "" == []
+ | otherwise = runLengthEncode (replicate m 'x') == [('x', m)]
+ where m = n `mod` 100
+
+rlePropRoundTrip :: [Int] -> Bool
+rlePropRoundTrip ns = runLengthEncode xs == is
+ where is = zip ['a'..] $ map (\n -> n `mod` 100 + 1) ns
+ xs = concatMap (\(i,n) -> replicate n i) is
+~~~~
+
+# Quick Check 'em:
+
+~~~~ {.haskell}
+> quickCheck rlePropRoundTrip
++++ OK, passed 100 tests.
+> quickCheck rlePropDupesCollapsed
++++ OK, passed 100 tests.
+> quickCheck rlePropRoundTrip
++++ OK, passed 100 tests.
+~~~~
+
+----
+
+Whew
+
+# Oh, and some more things:
+
+* ghci
+* cabal & hackage
+* haddock
+* Hoogle
+* `#haskell` on `irc.freenode.org`
+
+
+# Thanks
+
+Mark Lentczner
+
+`mark@glyphic.com`
+
+`mzero` on IRC
Please sign in to comment.
Something went wrong with that request. Please try again.