diff --git a/docs/home.js b/docs/home.js
--- a/docs/home.js
+++ b/docs/home.js
@@ -5,15 +5,15 @@
 var False = false;
 
 /*******************************************************************************
-* Thunks.
-*/
+ * Thunks.
+ */
 
 // Force a thunk (if it is a thunk) until WHNF.
 function _(thunkish,nocache){
-  while (thunkish instanceof $) {
-    thunkish = thunkish.force(nocache);
-  }
-  return thunkish;
+    while (thunkish instanceof $) {
+        thunkish = thunkish.force(nocache);
+    }
+    return thunkish;
 }
 
 // Apply a function to arguments (see method2 in Fay.hs).
@@ -27,344 +27,415 @@
 
 // Thunk object.
 function $(value){
-  this.forced = false;
-  this.value = value;
+    this.forced = false;
+    this.value = value;
 }
 
 // Force the thunk.
 $.prototype.force = function(nocache){
-  return nocache
-    ? this.value()
-    : this.forced
-    ? this.value
-    : (this.forced = true, this.value = this.value());
+    return nocache
+        ? this.value()
+        : this.forced
+        ? this.value
+        : (this.forced = true, this.value = this.value());
 };
 
 /*******************************************************************************
-* Constructors.
-*/
+ * Constructors.
+ */
 
 // A constructor.
 function Fay$$Constructor(){
-  this.name = arguments[0];
-  this.fields = Array.prototype.slice.call(arguments,1);
+    this.name = arguments[0];
+    this.fields = Array.prototype.slice.call(arguments,1);
 }
 
 // Eval in the context of the Haskell bindings.
 function Fay$$eval(str){
-  return eval(str);
+    return eval(str);
 }
 
 /*******************************************************************************
-* Monad.
-*/
+ * Monad.
+ */
 
 function Fay$$Monad(value){
-  this.value = value;
+    this.value = value;
 }
 
 // >>
 function Fay$$then(a){
-  return function(b){
-    return new $(function(){
-      _(a,true);
-      return b;
-    });
-  };
+    return function(b){
+        return new $(function(){
+            _(a,true);
+            return b;
+        });
+    };
 }
 
 // >>=
 function Fay$$bind(m){
-  return function(f){
-    return new $(function(){
-      var monad = _(m,true);
-      return f(monad.value);
-    });
-  };
+    return function(f){
+        return new $(function(){
+            var monad = _(m,true);
+            return f(monad.value);
+        });
+    };
 }
 
 var Fay$$unit = null;
 
 // return
 function Fay$$return(a){
-  return new Fay$$Monad(a);
+    return new Fay$$Monad(a);
 }
 
 /*******************************************************************************
-* FFI.
-*/
+ * FFI.
+ */
 
 // Serialize a Fay object to JS.
-function Fay$$serialize(type,obj){
-  type = _(type);
-  if(type) type = type[0].name;
-  if(type == "JsType"){
-    return function(){
-      return _(obj,true).value;
-    };
-  } else {
-    obj = _(obj);
-    if(type == "StringType" ||
-       (obj instanceof Fay$$Cons && typeof obj.car == 'string')){
-      var str = "";
-      while(obj instanceof Fay$$Cons) {
-        str += obj.car;
-        obj = _(obj.cdr);
-      }
-      return str;
-    } else if(type == "FunctionType" || typeof obj == 'function'){
-      return function(){
-        var out = obj;
-        for (var len = arguments.length, i = 0; i < len; i++){
-          if(typeof out != 'function') {
-            throw "Wrong number of arguments for callback: " + arguments.toString();
-          }
-          out = out(arguments[i]);
+function Fay$$serialize(type,fayObj){
+    var base = type[0];
+    var args = type[1];
+    var jsObj;
+    switch(base){
+    case "action": {
+        // A nullary monadic action. Should become a nullary JS function.
+        // Fay () -> function(){ return ... }
+        jsObj = function(){
+            return Fay$$serialize(args[0],_(fayObj,true).value);
+        };
+        break;
+    }
+    case "function": {
+        // A proper function.
+        jsObj = function(){
+            var return_type = args[args.length-1];
+            var len = args.length;
+            // If some arguments.
+            if (len > 1) {
+                // Apply to all the arguments.
+                fayObj = _(fayObj,true);
+                for (var i = 0, len = len; i < len - 1; i++) {
+                    // Unserialize the JS values to Fay for the Fay callback.
+                    fayObj = _(fayObj(Fay$$unserialize(args[i],arguments[i])),true);
+                }
+                // Finally, serialize the Fay return value back to JS.
+                var return_base = return_type[0];
+                var return_args = return_type[1];
+                // If it's a monadic return value, get the value instead.
+                if(return_base == "action") {
+                    return Fay$$serialize(return_args[0],fayObj.value);
+                }
+                // Otherwise just serialize the value direct.
+                else {
+                    return Fay$$serialize(return_type,fayObj);
+                }
+            } else {
+                throw new Error("Nullary function?");
+            }
+        };
+        break;
+    }
+    case "string": {
+        // Serialize Fay string to JavaScript string.
+        var str = "";
+        fayObj = _(fayObj);
+        while(fayObj instanceof Fay$$Cons) {
+            str += fayObj.car;
+            fayObj = _(fayObj.cdr);
         }
-        return _(out,true);
-      };
-    } else if(type == "ListType" || (obj instanceof Fay$$Cons)){
-      var arr = [];
-      while(obj instanceof Fay$$Cons) {
-        arr.push(Fay$$serialize(null,obj.car));
-        obj = _(obj.cdr);
-      }
-      return arr;
-    } // else if(type == "BoolType || obj == _(True) || obj == _(False)) {
-    //   return obj == _(True);
-    // }
-    else {
-      return obj;
+        jsObj = str;
+        break;
     }
-  }
+    case "list": {
+        // Serialize Fay list to JavaScript array.
+        var arr = [];
+        fayObj = _(fayObj);
+        while(fayObj instanceof Fay$$Cons) {
+            arr.push(Fay$$serialize(args[0],fayObj.car));
+            fayObj = _(fayObj.cdr);
+        }
+        jsObj = arr;
+        break;
+    }
+    case "double": {
+        // Serialize double, just force the argument. Doubles are unboxed.
+        jsObj = _(fayObj);
+        break;
+    }
+    case "unknown": {
+        // Just force unknown values to WHNF.
+        jsObj = _(fayObj);
+        break;
+    }
+    case "bool": {
+        // Bools are unboxed.
+        jsObj = fayObj;
+        break;
+    }
+    default: throw new Error("Unhandled serialize type: " + base);
+    }
+    return jsObj;
 }
 
+// Unserialize an object from JS to Fay.
+function Fay$$unserialize(type,jsObj){
+    var base = type[0];
+    var args = type[1];
+    var fayObj;
+    switch(base){
+    case "action": {
+        // Unserialize a "monadic" JavaScript return value into a monadic value.
+        fayObj = Fay$$return(Fay$$unserialize(args[0],jsObj));
+        break;
+    }
+    case "string": {
+        // Unserialize a JS string into Fay list (String).
+        fayObj = Fay$$list(jsObj);
+        break;
+    }
+    case "list": {
+        // Unserialize a JS array into a Fay list ([a]).
+        var serializedList = [];
+        for (var i = 0, len = jsObj.length; i < len; i++) {
+            // Unserialize each JS value into a Fay value, too.
+            serializedList.push(Fay$$unserialize(args[0],jsObj[i]));
+        }
+        // Pop it all in a Fay list.
+        fayObj = Fay$$list(serializedList);
+        break;
+    }
+    case "double": {
+        // Doubles are unboxed, so there's nothing to do.
+        fayObj = jsObj;
+        break;
+    }
+    case "unknown": {
+        // Any unknown values can be left as-is.
+        fayObj = jsObj;
+        break;
+    }
+    default: throw new Error("Unhandled unserialize type: " + base);
+    }
+    return fayObj;
+}
+
 // Encode a value to a Show representation
 function Fay$$encodeShow(x){
-  if (x instanceof $) x = _(x);
-  if (x instanceof Array) {
-    if (x.length == 0) {
-      return "[]";
-    } else {
-      if (x[0] instanceof Fay$$Constructor) {
-        if(x[0].fields.length > 0) {
-          var args = x.slice(1);
-          var fieldNames = x[0].fields;
-          return "(" + x[0].name + " { " + args.map(function(x,i){
-            return fieldNames[i] + ' = ' + Fay$$encodeShow(x);
-          }).join(", ") + " })";
+    if (x instanceof $) x = _(x);
+    if (x instanceof Array) {
+        if (x.length == 0) {
+            return "[]";
         } else {
-          var args = x.slice(1);
-          return "(" + [x[0].name].concat(args.map(Fay$$encodeShow)).join(" ") + ")";
+            if (x[0] instanceof Fay$$Constructor) {
+                if(x[0].fields.length > 0) {
+                    var args = x.slice(1);
+                    var fieldNames = x[0].fields;
+                    return "(" + x[0].name + " { " + args.map(function(x,i){
+                        return fieldNames[i] + ' = ' + Fay$$encodeShow(x);
+                    }).join(", ") + " })";
+                } else {
+                    var args = x.slice(1);
+                    return "(" + [x[0].name].concat(args.map(Fay$$encodeShow)).join(" ") + ")";
+                }
+            } else {
+                return "[" + x.map(Fay$$encodeShow).join(",") + "]";
+            }
         }
-      } else {
-        return "[" + x.map(Fay$$encodeShow).join(",") + "]";
-      }
+    } else if (typeof x == 'string') {
+        return JSON.stringify(x);
+    } else if(x instanceof Fay$$Cons) {
+        return Fay$$encodeShow(Fay$$serialize(["list",[["unknown"]]],x));
+    } else if(x == null) {
+        return '[]';
+    } else {
+        return x.toString();
     }
-  } else if (typeof x == 'string') {
-    return JSON.stringify(x);
-  } else if(x instanceof Fay$$Cons) {
-    return Fay$$encodeShow(Fay$$serialize(ListType,x));
-  } else if(x == null) {
-    return '[]';
-  } else {
-    return x.toString();
-  }
 }
 
-// Unserialize an object from JS to Fay.
-function Fay$$unserialize(typ,obj){
-  if(typ == 'string' || typ == 'array' || typ == 'list')
-    return Fay$$list(obj);
-  else if(typ == 'bool')
-    return obj? True : False;
-  else if(typ == 'data') {
-    alert('Time to unserialize a data record!');
-  }
-  else return obj;
-}
-
 /*******************************************************************************
-* Lists.
-*/
+ * Lists.
+ */
 
 // Cons object.
 function Fay$$Cons(car,cdr){
-  this.car = car;
-  this.cdr = cdr;
+    this.car = car;
+    this.cdr = cdr;
 }
 
 // Make a list.
 function Fay$$list(xs){
-  var out = null;
-  for(var i=xs.length-1; i>=0;i--)
-    out = new Fay$$Cons(xs[i],out);
-  return out;
+    var out = null;
+    for(var i=xs.length-1; i>=0;i--)
+        out = new Fay$$Cons(xs[i],out);
+    return out;
 }
 
 // Built-in list cons.
 function Fay$$cons(x){
-  return function(y){
-    return new Fay$$Cons(x,y);
-  };
+    return function(y){
+        return new Fay$$Cons(x,y);
+    };
 }
 
 // List index.
 function Fay$$index(index){
-  return function(list){
-    for(var i = 0; i < index; i++) {
-      list = _(list).cdr;
-    }
-    return list.car;
-  };
+    return function(list){
+        for(var i = 0; i < index; i++) {
+            list = _(list).cdr;
+        }
+        return list.car;
+    };
 }
 
 /*******************************************************************************
-* Numbers.
-*/
+ * Numbers.
+ */
 
 // Built-in *.
 function Fay$$mult(x){
-  return function(y){
-    return _(x) * _(y);
-  };
+    return function(y){
+        return _(x) * _(y);
+    };
 }
 
 // Built-in +.
 function Fay$$add(x){
-  return function(y){
-    return _(x) + _(y);
-  };
+    return function(y){
+        return _(x) + _(y);
+    };
 }
 
 // Built-in -.
 function Fay$$sub(x){
-  return function(y){
-    return _(x) - _(y);
-  };
+    return function(y){
+        return _(x) - _(y);
+    };
 }
 
 // Built-in /.
 function Fay$$div(x){
-  return function(y){
-    return _(x) / _(y);
-  };
+    return function(y){
+        return _(x) / _(y);
+    };
 }
 
 /*******************************************************************************
-* Booleans.
-*/
+ * Booleans.
+ */
 
 // Are two values equal?
 function Fay$$equal(lit1,lit2){
-  // Simple case
-  lit1 = _(lit1);
-  lit2 = _(lit2);
-  if(lit1 === lit2) {
-    return true;
-  }
-  // General case
-  if(lit1 instanceof Array) {
-    if(lit1.length!=lit2.length) return false;
-    for(var len = lit1.length, i = 0; i < len; i++) {
-      if(!Fay$$equal(lit1[i],lit2[i]))
-        return false;
+    // Simple case
+    lit1 = _(lit1);
+    lit2 = _(lit2);
+    if(lit1 === lit2) {
+        return true;
     }
-    return true;
-  } else if (lit1 instanceof Fay$$Cons) {
-    while(lit1 instanceof Fay$$Cons && lit2 instanceof Fay$$Cons && Fay$$equal(lit1.car,lit2.car))
-      lit1 = lit1.cdr, lit2 = lit2.cdr;
-    return (lit1 === null && lit2 === null);
-  } else return false;
+    // General case
+    if(lit1 instanceof Array) {
+        if(lit1.length!=lit2.length) return false;
+        for(var len = lit1.length, i = 0; i < len; i++) {
+            if(!Fay$$equal(lit1[i],lit2[i]))
+                return false;
+        }
+        return true;
+    } else if (lit1 instanceof Fay$$Cons) {
+        while(lit1 instanceof Fay$$Cons && lit2 instanceof Fay$$Cons && Fay$$equal(lit1.car,lit2.car))
+            lit1 = lit1.cdr, lit2 = lit2.cdr;
+        return (lit1 === null && lit2 === null);
+    } else return false;
 }
 
 // Built-in ==.
 function Fay$$eq(x){
-  return function(y){
-    return Fay$$equal(x,y);
-  };
+    return function(y){
+        return Fay$$equal(x,y);
+    };
 }
 
 // Built-in /=.
 function Fay$$neq(x){
-  return function(y){
-    return !(Fay$$equal(x,y));
-  };
+    return function(y){
+        return !(Fay$$equal(x,y));
+    };
 }
 
 // Built-in >.
 function Fay$$gt(x){
-  return function(y){
-    return _(x) > _(y);
-  };
+    return function(y){
+        return _(x) > _(y);
+    };
 }
 
 // Built-in <.
 function Fay$$lt(x){
-  return function(y){
-    return _(x) < _(y);
-  };
+    return function(y){
+        return _(x) < _(y);
+    };
 }
 
 // Built-in >=.
 function Fay$$gte(x){
-  return function(y){
-    return _(x) >= _(y);
-  };
+    return function(y){
+        return _(x) >= _(y);
+    };
 }
 
 // Built-in <=.
 function Fay$$lte(x){
-  return function(y){
-    return _(x) <= _(y);
-  };
+    return function(y){
+        return _(x) <= _(y);
+    };
 }
 
 // Built-in &&.
 function Fay$$and(x){
-  return function(y){
-    return _(x) && _(y);
-  };
+    return function(y){
+        return _(x) && _(y);
+    };
 }
 
 // Built-in ||.
 function Fay$$or(x){
-  return function(y){
-    return _(x) || _(y);
-  };
+    return function(y){
+        return _(x) || _(y);
+    };
 }
 
 /*******************************************************************************
-* Mutable references.
-*/
+ * Mutable references.
+ */
 
 // Make a new mutable reference.
 function Fay$$Ref(x){
-  this.value = x;
+    this.value = x;
 }
 
 // Write to the ref.
 function Fay$$writeRef(ref,x){
-  ref.value = x;
+    ref.value = x;
 }
 
 // Get the value from the ref.
 function Fay$$readRef(ref,x){
-  return ref.value;
+    return ref.value;
 }
 
 /*******************************************************************************
-* Dates.
-*/
+ * Dates.
+ */
 function Fay$$date(str){
-  return window.Date.parse(str);
+    return window.Date.parse(str);
 }
 
 /*******************************************************************************
-* Application code.
-*/
+ * Application code.
+ */
 
-var main = new $(function(){return _(_($36$)(_(ready)(_(wrap)(thedocument))))(_(_(Fay$$then)(indentAndHighlight))(_(_(Fay$$then)(setupExpanders))(_(_(Fay$$then)(setupTableOfContents))(_(_(Fay$$bind)(_(query)(Fay$$list(".subheadline"))))(function($_a){var body = $_a;return _(_(Fay$$then)(_(_(addClassWith)(function($_a){var i = $_a;return function($_b){var f = $_b;return _(_(Fay$$then)(_(alert)(_(show)(i))))(_(_(Fay$$then)(_(alert)(f)))(_(Fay$$return)(f)));};}))(body)))(_(Fay$$return)(Fay$$unit));})))));});var addClassWith = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_b).addClass(function(x,i){ return Fay$$serialize(FunctionType,$_a)(x,Fay$$list(i)); })));});};};var indentAndHighlight = new $(function(){return _(_(Fay$$bind)(_(query)(Fay$$list(".language-javascript"))))(function($_a){var samples = $_a;return _(_(Fay$$then)(_(_($36$)(_(each)(samples)))(function($_a){var i = $_a;return function($_b){var _$this = $_b;return (function(){var sample = new $(function(){return _(wrap)(_$this);});return _(_(Fay$$bind)(_(getText)(sample)))(function($_a){var text = $_a;return _(_(setText)(sample))(_(_(beautify)(text))(2));});})();};})))(_(_(Fay$$then)(_(_(setTabReplace)(hljs))(Fay$$list("    "))))(_(initHighlightingOnLoad)(hljs)));});});var setupExpanders = new $(function(){return _(_(Fay$$bind)(_(_(Fay$$bind)(_(query)(Fay$$list(".wrap"))))(getWidth)))(function($_a){var wrapwidth = $_a;return _(_(Fay$$bind)(_(query)(Fay$$list(".example"))))(function($_a){var examples = $_a;return _(_($36$)(_(each)(examples)))(function($_a){var i = $_a;return function($_b){var _$this = $_b;return _(_(Fay$$bind)(_(_(getFind)(_(wrap)(_$this)))(Fay$$list("tr"))))(function($_a){var tr = $_a;return _(_(Fay$$bind)(_(_(Fay$$bind)(_(_(getFind)(tr))(Fay$$list("td"))))(getFirst)))(function($_a){var left = $_a;return _(_(Fay$$then)(_(_(addClass)(left))(Fay$$list("left"))))(_(_(Fay$$bind)(_(getNext)(left)))(function($_a){var right = $_a;return _(_(Fay$$bind)(_(makeElement)(Fay$$list("<a class='toggle' href='javascript:'>Show JavaScript</a>"))))(function($_a){var toggle = $_a;return _(_(Fay$$bind)(_(_($36$)(Fay$$return))(_(_(Fay$$bind)(_(_(getIs)(right))(Fay$$list(":visible"))))(function($_a){var visible = $_a;return _(visible) ? _(_(Fay$$then)(_(_(setText)(toggle))(Fay$$list("Hide JavaScript"))))(_(_(_(swapClasses)(toggle))(Fay$$list("toggle-hide")))(Fay$$list("toggle-show"))) : _(_(Fay$$then)(_(_(setText)(toggle))(Fay$$list("Show JavaScript"))))(_(_(_(swapClasses)(toggle))(Fay$$list("toggle-show")))(Fay$$list("toggle-hide")));}))))(function($_a){var toggleButton = $_a;return _(_(Fay$$then)(_(_($36$)(_(setClick)(toggle)))(_(_($36$)(_(fadeToggle)(right)))(toggleButton))))(_(_(Fay$$bind)(_(getWidth)(tr)))(function($_a){var width = $_a;return _(_(Fay$$then)(_(_($36$)(_(when)(_(width) > _(_(wrapwidth) + _(_(20 * _(wrapwidth)) / 100)))))(_(hide)(right))))(_(_(Fay$$then)(toggleButton))(_(_(Fay$$bind)(_(_(getFind)(left))(Fay$$list(".panel"))))(function($_a){var panel = $_a;return _(_(Fay$$then)(_(_(prepend)(panel))(toggle)))(_(Fay$$return)(Fay$$unit));})));}));});});}));});});};});});});});var setupTableOfContents = new $(function(){return _(_(Fay$$bind)(_(makeElement)(Fay$$list("<div class='table-of-contents'><p>Table of Contents</p></div>"))))(function($_a){var toc = $_a;return _(_(Fay$$then)(_(_(Fay$$bind)(_(query)(Fay$$list(".subheadline"))))(_(after)(toc))))(_(_(Fay$$bind)(_(_(Fay$$bind)(_(makeElement)(Fay$$list("<ul></ul>"))))(_(appendTo)(toc))))(function($_a){var ul = $_a;return _(_(Fay$$bind)(_(query)(Fay$$list("h2"))))(function($_a){var headings = $_a;return _(_($36$)(_(each)(headings)))(function($_a){var i = $_a;return function($_b){var heading = $_b;return (function(){var anchor = new $(function(){return _(_($43$$43$)(Fay$$list("section-")))(_(show)(i));});var h = new $(function(){return _(wrap)(heading);});return _(_(Fay$$then)(_(_(_(attr)(h))(Fay$$list("id")))(anchor)))(_(_(Fay$$bind)(_(_(Fay$$bind)(_(makeElement)(Fay$$list("<li></li>"))))(_(appendTo)(ul))))(function($_a){var li = $_a;return _(_(Fay$$bind)(_(_(Fay$$bind)(_(makeElement)(Fay$$list("<a></a>"))))(_(appendTo)(li))))(function($_a){var a = $_a;return _(_(Fay$$then)(_(_(Fay$$bind)(_(getText)(h)))(_(setText)(a))))(_(_(Fay$$then)(_(_(_(attr)(a))(Fay$$list("href")))(_(_($43$$43$)(Fay$$list("#")))(anchor))))(_(_(Fay$$bind)(_(getTagName)(heading)))(_(addClass)(li))));});}));})();};});});}));});});var print = new $(function(){return _(_($46$)(consolelog))(show);});var consolelog = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",console.log(Fay$$serialize(StringType,$_a))));});};var alert = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",window.alert(Fay$$serialize(StringType,$_a))));});};var thedocument = new $(function(){return Fay$$unserialize("",window.document);});var getTagName = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("string",Fay$$serialize(UnknownType,$_a)['tagName']));});};var wrap = function($_a){return new $(function(){return Fay$$unserialize("",window['jQuery'](Fay$$serialize(UnknownType,$_a)));});};var ready = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['ready'](Fay$$serialize(JsType,$_b))));});};};var each = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['each'](Fay$$serialize(FunctionType,$_b))));});};};var query = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",window['jQuery'](Fay$$serialize(StringType,$_a))));});};var setText = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['text'](Fay$$serialize(StringType,$_b))));});};};var attr = function($_a){return function($_b){return function($_c){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['attr'](Fay$$serialize(StringType,$_b),Fay$$serialize(StringType,$_c))));});};};};var setClick = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['click'](Fay$$serialize(JsType,$_b))));});};};var fadeToggle = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['fadeToggle'](Fay$$serialize(JsType,$_b))));});};};var hide = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['hide']()));});};var addClass = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['addClass'](Fay$$serialize(StringType,$_b))));});};};var removeClass = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['removeClass'](Fay$$serialize(StringType,$_b))));});};};var swapClasses = function($_a){return function($_b){return function($_c){return new $(function(){var removeme = $_c;var addme = $_b;var obj = $_a;return _(_(Fay$$then)(_(_(addClass)(obj))(addme)))(_(_(removeClass)(obj))(removeme));});};};};var getText = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("string",Fay$$serialize(UnknownType,$_a)['text']()));});};var getIs = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("bool",Fay$$serialize(UnknownType,$_a)['is'](Fay$$serialize(StringType,$_b))));});};};var getSize = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['length']));});};var getNext = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['next']()));});};var getFirst = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['first']()));});};var getFind = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['find'](Fay$$serialize(StringType,$_b))));});};};var prepend = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['prepend'](Fay$$serialize(UnknownType,$_b))));});};};var after = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_b)['after'](Fay$$serialize(UnknownType,$_a))));});};};var append = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['append'](Fay$$serialize(UnknownType,$_b))));});};};var appendTo = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_b)['appendTo'](Fay$$serialize(UnknownType,$_a))));});};};var makeElement = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",window['jQuery'](Fay$$serialize(StringType,$_a))));});};var getWidth = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['width']()));});};var beautify = function($_a){return function($_b){return new $(function(){return Fay$$unserialize("string",$jsBeautify(Fay$$serialize(StringType,$_a),Fay$$serialize(DoubleType,$_b)));});};};var hljs = new $(function(){return Fay$$unserialize("",window['hljs']);});var initHighlightingOnLoad = function($_a){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['initHighlightingOnLoad']()));});};var setTabReplace = function($_a){return function($_b){return new $(function(){return new Fay$$Monad(Fay$$unserialize("",Fay$$serialize(UnknownType,$_a)['tabReplace']=Fay$$serialize(StringType,$_b)));});};};var DateType = new $(function(){return [new Fay$$Constructor("DateType")];});var FunctionType = new $(function(){return [new Fay$$Constructor("FunctionType")];});var JsType = new $(function(){return [new Fay$$Constructor("JsType")];});var StringType = new $(function(){return [new Fay$$Constructor("StringType")];});var DoubleType = new $(function(){return [new Fay$$Constructor("DoubleType")];});var ListType = new $(function(){return [new Fay$$Constructor("ListType")];});var BoolType = new $(function(){return [new Fay$$Constructor("BoolType")];});var UnknownType = new $(function(){return [new Fay$$Constructor("UnknownType")];});var Just = function(slot1){return new $(function(){return [new Fay$$Constructor("Just"),slot1];});};var Nothing = new $(function(){return [new Fay$$Constructor("Nothing")];});var show = function($_a){return new $(function(){return Fay$$unserialize("string",Fay$$encodeShow(Fay$$serialize(UnknownType,$_a)));});};var fromInteger = function($_a){return new $(function(){var x = $_a;return x;});};var fromRational = function($_a){return new $(function(){var x = $_a;return x;});};var snd = function($_a){return new $(function(){var x = Fay$$index(1)(_($_a));return x;throw ["unhandled case in Ident \"snd\"",[$_a]];});};var fst = function($_a){return new $(function(){var x = Fay$$index(0)(_($_a));return x;throw ["unhandled case in Ident \"fst\"",[$_a]];});};var find = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var p = $_a;return _(_(p)(x)) ? _(Just)(x) : _(_(find)(p))(xs);}if (_($_b) === null) {var p = $_a;return Nothing;}throw ["unhandled case in Ident \"find\"",[$_a,$_b]];});};};var any = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var p = $_a;return _(_(p)(x)) ? true : _(_(any)(p))(xs);}if (_($_b) === null) {var p = $_a;return false;}throw ["unhandled case in Ident \"any\"",[$_a,$_b]];});};};var filter = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var p = $_a;return _(_(p)(x)) ? _(_(Fay$$cons)(x))(_(_(filter)(p))(xs)) : _(_(filter)(p))(xs);}if (_($_b) === null) {return null;}throw ["unhandled case in Ident \"filter\"",[$_a,$_b]];});};};var not = function($_a){return new $(function(){var p = $_a;return _(p) ? false : true;});};var _$null = function($_a){return new $(function(){if (_($_a) === null) {return true;}return false;});};var map = function($_a){return function($_b){return new $(function(){if (_($_b) === null) {return null;}var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var f = $_a;return _(_(Fay$$cons)(_(f)(x)))(_(_(map)(f))(xs));}throw ["unhandled case in Ident \"map\"",[$_a,$_b]];});};};var nub = function($_a){return new $(function(){var ls = $_a;return _(_(nub$39$)(ls))(null);});};var nub$39$ = function($_a){return function($_b){return new $(function(){if (_($_a) === null) {return null;}var ls = $_b;var $_$_a = _($_a);if ($_$_a instanceof Fay$$Cons) {var x = $_$_a.car;var xs = $_$_a.cdr;return _(_(_(elem)(x))(ls)) ? _(_(nub$39$)(xs))(ls) : _(_(Fay$$cons)(x))(_(_(nub$39$)(xs))(_(_(Fay$$cons)(x))(ls)));}throw ["unhandled case in Ident \"nub'\"",[$_a,$_b]];});};};var elem = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var y = $_$_b.car;var ys = $_$_b.cdr;var x = $_a;return _(_(_(Fay$$eq)(x))(y)) || _(_(_(elem)(x))(ys));}if (_($_b) === null) {return false;}throw ["unhandled case in Ident \"elem\"",[$_a,$_b]];});};};var GT = new $(function(){return [new Fay$$Constructor("GT")];});var LT = new $(function(){return [new Fay$$Constructor("LT")];});var EQ = new $(function(){return [new Fay$$Constructor("EQ")];});var sort = new $(function(){return _(sortBy)(compare);});var compare = function($_a){return function($_b){return new $(function(){var y = $_b;var x = $_a;return _(_(x) > _(y)) ? GT : _(_(x) < _(y)) ? LT : EQ;});};};var sortBy = function($_a){return new $(function(){var cmp = $_a;return _(_(foldr)(_(insertBy)(cmp)))(null);});};var insertBy = function($_a){return function($_b){return function($_c){return new $(function(){if (_($_c) === null) {var x = $_b;return Fay$$list([x]);}var ys = $_c;var x = $_b;var cmp = $_a;return (function($_ys){var $_$_ys = _($_ys);if ($_$_ys instanceof Fay$$Cons) {var y = $_$_ys.car;var ys$39$ = $_$_ys.cdr;return (function($tmp){if ((_($tmp))[0].name === "GT") {return _(_(Fay$$cons)(y))(_(_(_(insertBy)(cmp))(x))(ys$39$));}return _(_(Fay$$cons)(x))(ys);})(_(_(cmp)(x))(y));}return (function(){ throw (["unhandled case",$_ys]); })();})(ys);});};};};var when = function($_a){return function($_b){return new $(function(){var m = $_b;var p = $_a;return _(p) ? _(_(Fay$$then)(m))(_(Fay$$return)(Fay$$unit)) : _(Fay$$return)(Fay$$unit);});};};var enumFrom = function($_a){return new $(function(){var i = $_a;return _(_(Fay$$cons)(i))(_(enumFrom)(_(i) + 1));});};var enumFromTo = function($_a){return function($_b){return new $(function(){var n = $_b;var i = $_a;return _(_(_(Fay$$eq)(i))(n)) ? Fay$$list([i]) : _(_(Fay$$cons)(i))(_(_(enumFromTo)(_(i) + 1))(n));});};};var zipWith = function($_a){return function($_b){return function($_c){return new $(function(){var $_$_c = _($_c);if ($_$_c instanceof Fay$$Cons) {var b = $_$_c.car;var bs = $_$_c.cdr;var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var a = $_$_b.car;var as = $_$_b.cdr;var f = $_a;return _(_(Fay$$cons)(_(_(f)(a))(b)))(_(_(_(zipWith)(f))(as))(bs));}}return null;});};};};var zip = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var b = $_$_b.car;var bs = $_$_b.cdr;var $_$_a = _($_a);if ($_$_a instanceof Fay$$Cons) {var a = $_$_a.car;var as = $_$_a.cdr;return _(_(Fay$$cons)(Fay$$list([a,b])))(_(_(zip)(as))(bs));}}return null;});};};var flip = function($_a){return function($_b){return function($_c){return new $(function(){var y = $_c;var x = $_b;var f = $_a;return _(_(f)(y))(x);});};};};var maybe = function($_a){return function($_b){return function($_c){return new $(function(){if ((_($_c))[0].name === "Nothing") {var f = $_b;var m = $_a;return m;}if ((_($_c))[0].name === "Just") {var x = (_($_c))[1];var f = $_b;var m = $_a;return _(f)(x);}throw ["unhandled case in Ident \"maybe\"",[$_a,$_b,$_c]];});};};};var $46$ = function($_a){return function($_b){return function($_c){return new $(function(){var x = $_c;var g = $_b;var f = $_a;return _(f)(_(g)(x));});};};};var $43$$43$ = function($_a){return function($_b){return new $(function(){var y = $_b;var x = $_a;return _(_(conc)(x))(y);});};};var $36$ = function($_a){return function($_b){return new $(function(){var x = $_b;var f = $_a;return _(f)(x);});};};var conc = function($_a){return function($_b){return new $(function(){var ys = $_b;var $_$_a = _($_a);if ($_$_a instanceof Fay$$Cons) {var x = $_$_a.car;var xs = $_$_a.cdr;return _(_(Fay$$cons)(x))(_(_(conc)(xs))(ys));}var ys = $_b;if (_($_a) === null) {return ys;}throw ["unhandled case in Ident \"conc\"",[$_a,$_b]];});};};var concat = new $(function(){return _(_(foldr)(conc))(null);});var foldr = function($_a){return function($_b){return function($_c){return new $(function(){if (_($_c) === null) {var z = $_b;var f = $_a;return z;}var $_$_c = _($_c);if ($_$_c instanceof Fay$$Cons) {var x = $_$_c.car;var xs = $_$_c.cdr;var z = $_b;var f = $_a;return _(_(f)(x))(_(_(_(foldr)(f))(z))(xs));}throw ["unhandled case in Ident \"foldr\"",[$_a,$_b,$_c]];});};};};var foldl = function($_a){return function($_b){return function($_c){return new $(function(){if (_($_c) === null) {var z = $_b;var f = $_a;return z;}var $_$_c = _($_c);if ($_$_c instanceof Fay$$Cons) {var x = $_$_c.car;var xs = $_$_c.cdr;var z = $_b;var f = $_a;return _(_(_(foldl)(f))(_(_(f)(z))(x)))(xs);}throw ["unhandled case in Ident \"foldl\"",[$_a,$_b,$_c]];});};};};var lookup = function($_a){return function($_b){return new $(function(){if (_($_b) === null) {var _key = $_a;return Nothing;}var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = Fay$$index(0)(_($_$_b.car));var y = Fay$$index(1)(_($_$_b.car));var xys = $_$_b.cdr;var key = $_a;return _(_(_(Fay$$eq)(key))(x)) ? _(Just)(y) : _(_(lookup)(key))(xys);}throw ["unhandled case in Ident \"lookup\"",[$_a,$_b]];});};};var intersperse = function($_a){return function($_b){return new $(function(){if (_($_b) === null) {return null;}var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var sep = $_a;return _(_(Fay$$cons)(x))(_(_(prependToAll)(sep))(xs));}throw ["unhandled case in Ident \"intersperse\"",[$_a,$_b]];});};};var prependToAll = function($_a){return function($_b){return new $(function(){if (_($_b) === null) {return null;}var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var sep = $_a;return _(_(Fay$$cons)(sep))(_(_(Fay$$cons)(x))(_(_(prependToAll)(sep))(xs)));}throw ["unhandled case in Ident \"prependToAll\"",[$_a,$_b]];});};};var intercalate = function($_a){return function($_b){return new $(function(){var xss = $_b;var xs = $_a;return _(concat)(_(_(intersperse)(xs))(xss));});};};var forM_ = function($_a){return function($_b){return new $(function(){var m = $_b;var $_$_a = _($_a);if ($_$_a instanceof Fay$$Cons) {var x = $_$_a.car;var xs = $_$_a.cdr;return _(_(Fay$$then)(_(m)(x)))(_(_(forM_)(xs))(m));}if (_($_a) === null) {return _(Fay$$return)(Fay$$unit);}throw ["unhandled case in Ident \"forM_\"",[$_a,$_b]];});};};var mapM_ = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var m = $_a;return _(_(Fay$$then)(_(m)(x)))(_(_(mapM_)(m))(xs));}if (_($_b) === null) {return _(Fay$$return)(Fay$$unit);}throw ["unhandled case in Ident \"mapM_\"",[$_a,$_b]];});};};
+var main = new $(function(){return _(_($36$)(_(ready)(_(wrap)(thedocument))))(_(_(Fay$$then)(indentAndHighlight))(_(_(Fay$$then)(setupExpanders))(setupTableOfContents)));});var indentAndHighlight = new $(function(){return _(_(Fay$$bind)(_(query)(Fay$$list(".language-javascript"))))(function($_a){var samples = $_a;return _(_(Fay$$then)(_(_($36$)(_(each)(samples)))(function($_a){var i = $_a;return function($_b){var _$this = $_b;return (function(){var sample = new $(function(){return _(wrap)(_$this);});return _(_(Fay$$bind)(_(getText)(sample)))(function($_a){var text = $_a;return _(_(setText)(sample))(_(_(beautify)(text))(2));});})();};})))(_(_(Fay$$then)(_(_(setTabReplace)(hljs))(Fay$$list("    "))))(_(initHighlightingOnLoad)(hljs)));});});var setupExpanders = new $(function(){return _(_(Fay$$bind)(_(_(Fay$$bind)(_(query)(Fay$$list(".wrap"))))(getWidth)))(function($_a){var wrapwidth = $_a;return _(_(Fay$$bind)(_(query)(Fay$$list(".example"))))(function($_a){var examples = $_a;return _(_($36$)(_(each)(examples)))(function($_a){var i = $_a;return function($_b){var _$this = $_b;return _(_(Fay$$bind)(_(_(getFind)(_(wrap)(_$this)))(Fay$$list("tr"))))(function($_a){var tr = $_a;return _(_(Fay$$bind)(_(_(Fay$$bind)(_(_(getFind)(tr))(Fay$$list("td"))))(getFirst)))(function($_a){var left = $_a;return _(_(Fay$$then)(_(_(addClass)(left))(Fay$$list("left"))))(_(_(Fay$$bind)(_(getNext)(left)))(function($_a){var right = $_a;return _(_(Fay$$bind)(_(makeElement)(Fay$$list("<a class='toggle' href='javascript:'>Show JavaScript</a>"))))(function($_a){var toggle = $_a;return _(_(Fay$$bind)(_(_($36$)(Fay$$return))(_(_(Fay$$bind)(_(_(getIs)(right))(Fay$$list(":visible"))))(function($_a){var visible = $_a;return _(visible) ? _(_(Fay$$then)(_(_(setText)(toggle))(Fay$$list("Hide JavaScript"))))(_(_(_(swapClasses)(toggle))(Fay$$list("toggle-hide")))(Fay$$list("toggle-show"))) : _(_(Fay$$then)(_(_(setText)(toggle))(Fay$$list("Show JavaScript"))))(_(_(_(swapClasses)(toggle))(Fay$$list("toggle-show")))(Fay$$list("toggle-hide")));}))))(function($_a){var toggleButton = $_a;return _(_(Fay$$then)(_(_($36$)(_(setClick)(toggle)))(_(_($36$)(_(fadeToggle)(right)))(toggleButton))))(_(_(Fay$$bind)(_(getWidth)(tr)))(function($_a){var width = $_a;return _(_(Fay$$then)(_(_($36$)(_(when)(_(width) > _(_(wrapwidth) + _(_(20 * _(wrapwidth)) / 100)))))(_(hide)(right))))(_(_(Fay$$then)(toggleButton))(_(_(Fay$$bind)(_(_(getFind)(left))(Fay$$list(".panel"))))(function($_a){var panel = $_a;return _(_(Fay$$then)(_(_(prepend)(panel))(toggle)))(_(Fay$$return)(Fay$$unit));})));}));});});}));});});};});});});});var setupTableOfContents = new $(function(){return _(_(Fay$$bind)(_(makeElement)(Fay$$list("<div class='table-of-contents'><p>Table of Contents</p></div>"))))(function($_a){var toc = $_a;return _(_(Fay$$then)(_(_(Fay$$bind)(_(query)(Fay$$list(".subheadline"))))(_(after)(toc))))(_(_(Fay$$bind)(_(_(Fay$$bind)(_(makeElement)(Fay$$list("<ul></ul>"))))(_(appendTo)(toc))))(function($_a){var ul = $_a;return _(_(Fay$$bind)(_(query)(Fay$$list("h2"))))(function($_a){var headings = $_a;return _(_($36$)(_(each)(headings)))(function($_a){var i = $_a;return function($_b){var heading = $_b;return (function(){var anchor = new $(function(){return _(_($43$$43$)(Fay$$list("section-")))(_(show)(i));});var h = new $(function(){return _(wrap)(heading);});return _(_(Fay$$then)(_(_(_(attr)(h))(Fay$$list("id")))(anchor)))(_(_(Fay$$bind)(_(_(Fay$$bind)(_(makeElement)(Fay$$list("<li></li>"))))(_(appendTo)(ul))))(function($_a){var li = $_a;return _(_(Fay$$bind)(_(_(Fay$$bind)(_(makeElement)(Fay$$list("<a></a>"))))(_(appendTo)(li))))(function($_a){var a = $_a;return _(_(Fay$$then)(_(_(Fay$$bind)(_(getText)(h)))(_(setText)(a))))(_(_(Fay$$then)(_(_(_(attr)(a))(Fay$$list("href")))(_(_($43$$43$)(Fay$$list("#")))(anchor))))(_(_(Fay$$bind)(_(getTagName)(heading)))(_(addClass)(li))));});}));})();};});});}));});});var print = new $(function(){return _(_($46$)(consolelog))(show);});var consolelog = new $(function(){return _(_(ffi)(Fay$$list("console.log(%1)")))(FayNone);});var alert = new $(function(){return _(_(ffi)(Fay$$list("window.alert(%1)")))(FayNone);});var thedocument = new $(function(){return _(_(ffi)(Fay$$list("window.document")))(FayNone);});var getTagName = new $(function(){return _(_(ffi)(Fay$$list("%1['tagName']")))(FayString);});var wrap = new $(function(){return _(_(ffi)(Fay$$list("window['jQuery'](%1)")))(FayNone);});var ready = new $(function(){return _(_(ffi)(Fay$$list("%1['ready'](%2)")))(FayNone);});var each = new $(function(){return _(_(ffi)(Fay$$list("%1['each'](%2)")))(FayNone);});var query = new $(function(){return _(_(ffi)(Fay$$list("window['jQuery'](%1)")))(FayNone);});var setText = new $(function(){return _(_(ffi)(Fay$$list("%1['text'](%2)")))(FayNone);});var attr = new $(function(){return _(_(ffi)(Fay$$list("%1['attr'](%2,%3)")))(FayNone);});var setClick = new $(function(){return _(_(ffi)(Fay$$list("%1['click'](%2)")))(FayNone);});var fadeToggle = new $(function(){return _(_(ffi)(Fay$$list("%1['fadeToggle'](%2)")))(FayNone);});var hide = new $(function(){return _(_(ffi)(Fay$$list("%1['hide']()")))(FayNone);});var addClass = new $(function(){return _(_(ffi)(Fay$$list("%1['addClass'](%2)")))(FayNone);});var removeClass = new $(function(){return _(_(ffi)(Fay$$list("%1['removeClass'](%2)")))(FayNone);});var swapClasses = function($_a){return function($_b){return function($_c){return new $(function(){var removeme = $_c;var addme = $_b;var obj = $_a;return _(_(Fay$$then)(_(_(addClass)(obj))(addme)))(_(_(removeClass)(obj))(removeme));});};};};var getText = new $(function(){return _(_(ffi)(Fay$$list("%1['text']()")))(FayString);});var getIs = new $(function(){return _(_(ffi)(Fay$$list("%1['is'](%2)")))(FayBool);});var getSize = new $(function(){return _(_(ffi)(Fay$$list("%1['length']")))(FayNone);});var getNext = new $(function(){return _(_(ffi)(Fay$$list("%1['next']()")))(FayNone);});var getFirst = new $(function(){return _(_(ffi)(Fay$$list("%1['first']()")))(FayNone);});var getFind = new $(function(){return _(_(ffi)(Fay$$list("%1['find'](%2)")))(FayNone);});var prepend = new $(function(){return _(_(ffi)(Fay$$list("%1['prepend'](%2)")))(FayNone);});var after = new $(function(){return _(_(ffi)(Fay$$list("%2['after'](%1)")))(FayNone);});var append = new $(function(){return _(_(ffi)(Fay$$list("%1['append'](%2)")))(FayNone);});var appendTo = new $(function(){return _(_(ffi)(Fay$$list("%2['appendTo'](%1)")))(FayNone);});var makeElement = new $(function(){return _(_(ffi)(Fay$$list("window['jQuery'](%1)")))(FayNone);});var getWidth = new $(function(){return _(_(ffi)(Fay$$list("%1['width']()")))(FayNone);});var beautify = new $(function(){return _(_(ffi)(Fay$$list("$jsBeautify(%1,%2)")))(FayString);});var hljs = new $(function(){return _(_(ffi)(Fay$$list("window['hljs']")))(FayNone);});var initHighlightingOnLoad = new $(function(){return _(_(ffi)(Fay$$list("%1['initHighlightingOnLoad']()")))(FayNone);});var setTabReplace = new $(function(){return _(_(ffi)(Fay$$list("%1['tabReplace']=%2")))(FayNone);});var Just = function(slot1){return new $(function(){return [new Fay$$Constructor("Just"),slot1];});};var Nothing = new $(function(){return [new Fay$$Constructor("Nothing")];});var show = function($_a){return new $(function(){return Fay$$unserialize(["string"],Fay$$encodeShow(Fay$$serialize(["unknown"],$_a)));});};var fromInteger = function($_a){return new $(function(){var x = $_a;return x;});};var fromRational = function($_a){return new $(function(){var x = $_a;return x;});};var snd = function($_a){return new $(function(){var x = Fay$$index(1)(_($_a));return x;throw ["unhandled case in Ident \"snd\"",[$_a]];});};var fst = function($_a){return new $(function(){var x = Fay$$index(0)(_($_a));return x;throw ["unhandled case in Ident \"fst\"",[$_a]];});};var find = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var p = $_a;return _(_(p)(x)) ? _(Just)(x) : _(_(find)(p))(xs);}if (_($_b) === null) {var p = $_a;return Nothing;}throw ["unhandled case in Ident \"find\"",[$_a,$_b]];});};};var any = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var p = $_a;return _(_(p)(x)) ? true : _(_(any)(p))(xs);}if (_($_b) === null) {var p = $_a;return false;}throw ["unhandled case in Ident \"any\"",[$_a,$_b]];});};};var filter = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var p = $_a;return _(_(p)(x)) ? _(_(Fay$$cons)(x))(_(_(filter)(p))(xs)) : _(_(filter)(p))(xs);}if (_($_b) === null) {return null;}throw ["unhandled case in Ident \"filter\"",[$_a,$_b]];});};};var not = function($_a){return new $(function(){var p = $_a;return _(p) ? false : true;});};var _$null = function($_a){return new $(function(){if (_($_a) === null) {return true;}return false;});};var map = function($_a){return function($_b){return new $(function(){if (_($_b) === null) {return null;}var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var f = $_a;return _(_(Fay$$cons)(_(f)(x)))(_(_(map)(f))(xs));}throw ["unhandled case in Ident \"map\"",[$_a,$_b]];});};};var nub = function($_a){return new $(function(){var ls = $_a;return _(_(nub$39$)(ls))(null);});};var nub$39$ = function($_a){return function($_b){return new $(function(){if (_($_a) === null) {return null;}var ls = $_b;var $_$_a = _($_a);if ($_$_a instanceof Fay$$Cons) {var x = $_$_a.car;var xs = $_$_a.cdr;return _(_(_(elem)(x))(ls)) ? _(_(nub$39$)(xs))(ls) : _(_(Fay$$cons)(x))(_(_(nub$39$)(xs))(_(_(Fay$$cons)(x))(ls)));}throw ["unhandled case in Ident \"nub'\"",[$_a,$_b]];});};};var elem = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var y = $_$_b.car;var ys = $_$_b.cdr;var x = $_a;return _(_(_(Fay$$eq)(x))(y)) || _(_(_(elem)(x))(ys));}if (_($_b) === null) {return false;}throw ["unhandled case in Ident \"elem\"",[$_a,$_b]];});};};var GT = new $(function(){return [new Fay$$Constructor("GT")];});var LT = new $(function(){return [new Fay$$Constructor("LT")];});var EQ = new $(function(){return [new Fay$$Constructor("EQ")];});var sort = new $(function(){return _(sortBy)(compare);});var compare = function($_a){return function($_b){return new $(function(){var y = $_b;var x = $_a;return _(_(x) > _(y)) ? GT : _(_(x) < _(y)) ? LT : EQ;});};};var sortBy = function($_a){return new $(function(){var cmp = $_a;return _(_(foldr)(_(insertBy)(cmp)))(null);});};var insertBy = function($_a){return function($_b){return function($_c){return new $(function(){if (_($_c) === null) {var x = $_b;return Fay$$list([x]);}var ys = $_c;var x = $_b;var cmp = $_a;return (function($_ys){var $_$_ys = _($_ys);if ($_$_ys instanceof Fay$$Cons) {var y = $_$_ys.car;var ys$39$ = $_$_ys.cdr;return (function($tmp){if ((_($tmp))[0].name === "GT") {return _(_(Fay$$cons)(y))(_(_(_(insertBy)(cmp))(x))(ys$39$));}return _(_(Fay$$cons)(x))(ys);})(_(_(cmp)(x))(y));}return (function(){ throw (["unhandled case",$_ys]); })();})(ys);});};};};var when = function($_a){return function($_b){return new $(function(){var m = $_b;var p = $_a;return _(p) ? _(_(Fay$$then)(m))(_(Fay$$return)(Fay$$unit)) : _(Fay$$return)(Fay$$unit);});};};var enumFrom = function($_a){return new $(function(){var i = $_a;return _(_(Fay$$cons)(i))(_(enumFrom)(_(i) + 1));});};var enumFromTo = function($_a){return function($_b){return new $(function(){var n = $_b;var i = $_a;return _(_(_(Fay$$eq)(i))(n)) ? Fay$$list([i]) : _(_(Fay$$cons)(i))(_(_(enumFromTo)(_(i) + 1))(n));});};};var zipWith = function($_a){return function($_b){return function($_c){return new $(function(){var $_$_c = _($_c);if ($_$_c instanceof Fay$$Cons) {var b = $_$_c.car;var bs = $_$_c.cdr;var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var a = $_$_b.car;var as = $_$_b.cdr;var f = $_a;return _(_(Fay$$cons)(_(_(f)(a))(b)))(_(_(_(zipWith)(f))(as))(bs));}}return null;});};};};var zip = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var b = $_$_b.car;var bs = $_$_b.cdr;var $_$_a = _($_a);if ($_$_a instanceof Fay$$Cons) {var a = $_$_a.car;var as = $_$_a.cdr;return _(_(Fay$$cons)(Fay$$list([a,b])))(_(_(zip)(as))(bs));}}return null;});};};var flip = function($_a){return function($_b){return function($_c){return new $(function(){var y = $_c;var x = $_b;var f = $_a;return _(_(f)(y))(x);});};};};var maybe = function($_a){return function($_b){return function($_c){return new $(function(){if ((_($_c))[0].name === "Nothing") {var f = $_b;var m = $_a;return m;}if ((_($_c))[0].name === "Just") {var x = (_($_c))[1];var f = $_b;var m = $_a;return _(f)(x);}throw ["unhandled case in Ident \"maybe\"",[$_a,$_b,$_c]];});};};};var $46$ = function($_a){return function($_b){return function($_c){return new $(function(){var x = $_c;var g = $_b;var f = $_a;return _(f)(_(g)(x));});};};};var $43$$43$ = function($_a){return function($_b){return new $(function(){var y = $_b;var x = $_a;return _(_(conc)(x))(y);});};};var $36$ = function($_a){return function($_b){return new $(function(){var x = $_b;var f = $_a;return _(f)(x);});};};var conc = function($_a){return function($_b){return new $(function(){var ys = $_b;var $_$_a = _($_a);if ($_$_a instanceof Fay$$Cons) {var x = $_$_a.car;var xs = $_$_a.cdr;return _(_(Fay$$cons)(x))(_(_(conc)(xs))(ys));}var ys = $_b;if (_($_a) === null) {return ys;}throw ["unhandled case in Ident \"conc\"",[$_a,$_b]];});};};var concat = new $(function(){return _(_(foldr)(conc))(null);});var foldr = function($_a){return function($_b){return function($_c){return new $(function(){if (_($_c) === null) {var z = $_b;var f = $_a;return z;}var $_$_c = _($_c);if ($_$_c instanceof Fay$$Cons) {var x = $_$_c.car;var xs = $_$_c.cdr;var z = $_b;var f = $_a;return _(_(f)(x))(_(_(_(foldr)(f))(z))(xs));}throw ["unhandled case in Ident \"foldr\"",[$_a,$_b,$_c]];});};};};var foldl = function($_a){return function($_b){return function($_c){return new $(function(){if (_($_c) === null) {var z = $_b;var f = $_a;return z;}var $_$_c = _($_c);if ($_$_c instanceof Fay$$Cons) {var x = $_$_c.car;var xs = $_$_c.cdr;var z = $_b;var f = $_a;return _(_(_(foldl)(f))(_(_(f)(z))(x)))(xs);}throw ["unhandled case in Ident \"foldl\"",[$_a,$_b,$_c]];});};};};var lookup = function($_a){return function($_b){return new $(function(){if (_($_b) === null) {var _key = $_a;return Nothing;}var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = Fay$$index(0)(_($_$_b.car));var y = Fay$$index(1)(_($_$_b.car));var xys = $_$_b.cdr;var key = $_a;return _(_(_(Fay$$eq)(key))(x)) ? _(Just)(y) : _(_(lookup)(key))(xys);}throw ["unhandled case in Ident \"lookup\"",[$_a,$_b]];});};};var intersperse = function($_a){return function($_b){return new $(function(){if (_($_b) === null) {return null;}var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var sep = $_a;return _(_(Fay$$cons)(x))(_(_(prependToAll)(sep))(xs));}throw ["unhandled case in Ident \"intersperse\"",[$_a,$_b]];});};};var prependToAll = function($_a){return function($_b){return new $(function(){if (_($_b) === null) {return null;}var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var sep = $_a;return _(_(Fay$$cons)(sep))(_(_(Fay$$cons)(x))(_(_(prependToAll)(sep))(xs)));}throw ["unhandled case in Ident \"prependToAll\"",[$_a,$_b]];});};};var intercalate = function($_a){return function($_b){return new $(function(){var xss = $_b;var xs = $_a;return _(concat)(_(_(intersperse)(xs))(xss));});};};var forM_ = function($_a){return function($_b){return new $(function(){var m = $_b;var $_$_a = _($_a);if ($_$_a instanceof Fay$$Cons) {var x = $_$_a.car;var xs = $_$_a.cdr;return _(_(Fay$$then)(_(m)(x)))(_(_(forM_)(xs))(m));}if (_($_a) === null) {return _(Fay$$return)(Fay$$unit);}throw ["unhandled case in Ident \"forM_\"",[$_a,$_b]];});};};var mapM_ = function($_a){return function($_b){return new $(function(){var $_$_b = _($_b);if ($_$_b instanceof Fay$$Cons) {var x = $_$_b.car;var xs = $_$_b.cdr;var m = $_a;return _(_(Fay$$then)(_(m)(x)))(_(_(mapM_)(m))(xs));}if (_($_b) === null) {return _(Fay$$return)(Fay$$unit);}throw ["unhandled case in Ident \"mapM_\"",[$_a,$_b]];});};};
 // Exports
 this.main = main;
 
@@ -374,6 +445,7 @@
 this.$list       = Fay$$list;
 this.$encodeShow = Fay$$encodeShow;
 this.$eval       = Fay$$eval;
+this.$serialize  = Fay$$serialize;
 
 };
 ;
diff --git a/docs/snippets/ffi.hs b/docs/snippets/ffi.hs
--- a/docs/snippets/ffi.hs
+++ b/docs/snippets/ffi.hs
@@ -1,17 +1,17 @@
 print :: Foreign a => a -> Fay ()
-print = ffi "window.console.log(%1)" ""
+print = ffi "window.console.log(%1)"
 
 alert :: Foreign a => a -> Fay ()
-alert = ffi "window.alert(%1)" ""
+alert = ffi "window.alert(%1)"
 
 getInnerHtml :: Element -> Fay String
-getInnerHtml = ffi "%1.innerHTML" FayString
+getInnerHtml = ffi "%1.innerHTML"
 
 setInnerHtml :: Element -> String -> Fay ()
 setInnerHtml = ffi "%1.innerHTML=%2"
 
 thedocument :: Element
-thedocument = ffi "window.document" FayNone
+thedocument = ffi "window.document"
 
 jquery :: Element -> JQuery
-jquery = ffi "window.jQuery(%1)" FayNone
+jquery = ffi "window.jQuery(%1)"
diff --git a/examples/dom.hs b/examples/dom.hs
--- a/examples/dom.hs
+++ b/examples/dom.hs
@@ -19,6 +19,7 @@
 
 data Element
 instance Foreign Element
+instance Show (Element)
 
 documentGetElements :: String -> Fay [Element]
 documentGetElements = ffi "document.getElementsByTagName(%1)"
diff --git a/fay.cabal b/fay.cabal
--- a/fay.cabal
+++ b/fay.cabal
@@ -1,5 +1,5 @@
 name:                fay
-version:             0.5.0.0
+version:             0.5.1.0
 synopsis:            A compiler for Fay, a Haskell subset that compiles to JavaScript.
 description:         Fay is a proper subset of Haskell which can be compiled (type-checked)
                      with GHC, and compiled to JavaScript. It is lazy, pure, with a Fay monad,
@@ -22,7 +22,7 @@
                      .
                      /Release Notes/
                      .
-                     * MAJOR FFI RESTRUCTURING. Please see commit d6c346c320245762432928bc83aa8ca98a426138.
+                     * New representation for records and support for RecDecl (closes #43)
                      .
                      See full history at: <https://github.com/chrisdone/fay/commits>
 homepage:            http://fay-lang.org/
diff --git a/src/Language/Fay.hs b/src/Language/Fay.hs
--- a/src/Language/Fay.hs
+++ b/src/Language/Fay.hs
@@ -22,6 +22,7 @@
 import           Control.Monad.IO
 import           Control.Monad.State
 import           Data.Char
+import           Data.Default (def)
 import           Data.List
 import           Data.Maybe
 import           Data.String
@@ -90,6 +91,11 @@
     Right (ok,_) -> do writeFile "/tmp/x.js" ok
                        prettyPrintFile "/tmp/x.js" >>= putStr
 
+-- | Compile a String of Fay and print it as beautified JavaScript.
+printTestCompile :: String -> IO ()
+printTestCompile = printCompile def compileModule
+
+
 --------------------------------------------------------------------------------
 -- Compilers
 
@@ -116,7 +122,7 @@
   cfg <- config id
   result <- liftIO $ compileToAst cfg compileModule contents
   case result of
-    Right (stmts,state) -> return stmts
+    Right (stmts,_) -> return stmts
     Left err -> throwError err
     where replace c r = map (\x -> if x == c then r else x)
 compileImport i =
@@ -163,6 +169,8 @@
           Just sig -> compileFFI ident formatstr sig
           Nothing  -> throwError (FfiNeedsTypeSig pat)
         _ -> compileNormalPatBind toplevel ident rhs
+    PatBind _ (PVar ident) Nothing (UnGuardedRhs rhs) bdecls ->
+      compileNormalPatBind toplevel ident (Let bdecls rhs)
     _ -> throwError (UnsupportedDeclaration pat)
 
   where ffiExp (App (Var (UnQual (Ident "ffi"))) (Lit (String formatstr))) = Just formatstr
@@ -288,33 +296,59 @@
   fmap concat $
     forM constructors $ \(QualConDecl _ _ _ condecl) ->
       case condecl of
-        ConDecl (UnQual -> name) types  -> fmap return (makeDataCons name types [])
+        ConDecl (UnQual -> name) types  -> do
+          cons <- makeConstructor name (slots types)
+          func <- makeFunc name (slots types)
+          return [cons, func]
         RecDecl (UnQual -> name) fields -> do
-          cons <- makeDataCons name (map snd fields) (map fst fields)
-          funs <- makeAccessors (zip [1..] (map fst fields))
-          return (cons : funs)
+          cons <- makeConstructor name $ map (head . fst) fields
+          func <- makeFunc name $ map (head . fst) fields
+          funs <- makeAccessors (map fst fields)
+          return (cons : func : funs)
         _ -> throwError (UnsupportedDeclaration decl)
 
-  where makeDataCons name types fields = do
-          let slots = (map (fromString . ("slot"++) . show . fst)
-                           (zip [1 :: Integer ..] types))
+  where
+    slots :: [a] -> [Name]
+    slots = map (Ident . ("slot"++) . show . fst) . zip [1 :: Integer ..]
+
+    constructorName = fromString . (++ "_RecConstr") . qname
+
+    -- Creates a constructor R_RecConstr for a Record
+    makeConstructor name fields = do
+          let fieldParams = map (fromString . unname) fields
+          -- this._fields = [fieldName1, fieldName2, ..]
+          let setFields = JsSetProp (fromString ":this") (fromString "_fields")
+                 (JsList . flip map fields $ \(Ident field) -> JsLit . JsStr $ field)
+
           return $
-            JsVar name
-                  (foldr (\slot inner -> JsFun [slot] [] (Just inner))
-                         (thunk (JsList ((JsNew (hjIdent "Constructor")
-                                                (JsLit (JsStr (qname name)) :
-                                                 concat (map (map (JsLit . JsStr . unname)) fields)))
-                                         : map JsName slots)))
-                         slots)
-        makeAccessors fields = do
+            JsVar (constructorName name) $
+              JsFun fieldParams
+                (setFields :
+                  (flip map fields $
+                     \field@(Ident s) ->
+                       JsSetProp (fromString ":this") (UnQual field) (JsName (fromString s))))
+                Nothing
+
+    -- Creates a function to initialize the record by regular application
+    makeFunc name fields = do
+          let fieldParams = map (\(Ident s) -> fromString s) fields
+          let fieldExps = map (JsName . UnQual) fields
+          return $
+            JsVar name $
+              foldr (\slot inner -> JsFun [slot] [] (Just inner))
+                (thunk $ JsNew (constructorName name) fieldExps)
+                fieldParams
+
+    -- Creates getters for a RecDecl's values
+    makeAccessors fields = do
           fmap concat $
-            forM fields $ \(i,field) ->
-              forM field $ \name ->
+            forM fields $ \field ->
+              forM field $ \name@(Ident nameStr) ->
                 bindToplevel toplevel
                              (UnQual name)
                              (JsFun ["x"]
                                     []
-                                    (Just (thunk (JsIndex i (force (JsName "x"))))))
+                                    (Just (thunk (JsGetProp (force (JsName "x")) (UnQual (Ident nameStr))))))
 
 -- | Extract the string from a qname.
 qname :: QName -> String
@@ -395,9 +429,14 @@
   fmap concat (mapM flatten xs)
 expand _ = Nothing
 
--- -- | Run a JS file.
+-- | Format a JS file using "js-beautify", or return the JS as-is if
+--   "js-beautify" is unavailable
 prettyPrintFile :: String -> IO String
-prettyPrintFile file = fmap (either id id) (readAllFromProcess "js-beautify" file)
+prettyPrintFile file =
+  (readAllFromProcess "js-beautify" file)
+  >>= (either
+       (\_ -> (readFile file) >>= (\js -> return $ js ++ "\n"))
+       return)
 
 -- | Compile a right-hand-side expression.
 compileRhs :: Rhs -> Compile JsExp
@@ -461,12 +500,14 @@
                                         t <- compileExp i'
                                         return (JsApp (JsApp (JsName "enumFromTo") [f])
                                                       [t])
+    RecConstr name fieldUpdates -> compileRecConstr name fieldUpdates
     ExpTypeSig _ e _ -> compileExp e
 
     exp -> throwError (UnsupportedExpression exp)
 
 instance CompilesTo Exp JsExp where compileTo = compileExp
 
+
 -- | Compile simple application.
 compileApp :: Exp -> Exp -> Compile JsExp
 compileApp exp1 exp2 = do
@@ -518,6 +559,7 @@
   exps <- mapM compileExp xs
   return (makeList exps)
 
+makeList :: [JsExp] -> JsExp
 makeList exps = (JsApp (JsName (hjIdent "list")) [JsList exps])
 
 -- | Compile an if.
@@ -619,11 +661,24 @@
                body
                []]
 
+-- | Compile as binding in pattern match
 compilePAsPat :: JsExp -> Name -> Pat -> [JsStmt] -> Compile [JsStmt]
 compilePAsPat exp name pat body = do
-  x <- compilePat exp pat body;
+  x <- compilePat exp pat body
   return ([JsVar (UnQual name) exp] ++ x ++ body)
 
+-- | Compile a record construction with named fields
+-- | GHC will warn on uninitialized fields, they will be undefined in JS.
+compileRecConstr :: QName -> [FieldUpdate] -> Compile JsExp
+compileRecConstr name fieldUpdates = do
+    let o = UnQual (Ident (map toLower (qname name)))
+    -- var obj = new Type_RecConstr()
+    let record = JsVar o (JsNew (UnQual (Ident ((qname name) ++ "_RecConstr"))) [])
+    setFields <- forM fieldUpdates $
+           -- obj.field = value
+           \(FieldUpdate (UnQual field) value) -> JsSetProp o (UnQual field) <$> compileExp value
+    return $ JsApp (JsFun [] (record:setFields) (Just (JsName o))) []
+
 -- | Equality test for two expressions, with some optimizations.
 equalExps :: JsExp -> JsExp -> JsExp
 equalExps a b
@@ -642,18 +697,19 @@
 compilePApp :: QName -> [Pat] -> JsExp -> [JsStmt] -> Compile [JsStmt]
 compilePApp cons pats exp body = do
   let forcedExp = force exp
-  substmts <- foldM (\body (i,pat) -> compilePat (JsIndex i forcedExp) pat body)
+  substmts <- foldM (\body (fieldIndex,pat) ->
+                       -- r[r._fields[N]]
+                       compilePat (JsLookup forcedExp
+                                   (JsIndex fieldIndex
+                                    (JsGetProp forcedExp "_fields"))) pat body)
                     body
-                    (reverse (zip [1..] pats))
-  let constructor = JsIndex 0 forcedExp
-      compareConstructorNames
+                    (reverse (zip [0..] pats))
+  let compareConstructorNames
         -- Special-casing on the booleans.
         | cons == "True" = JsEq forcedExp (JsLit (JsBool True))
         | cons == "False" = JsEq forcedExp (JsLit (JsBool False))
         -- Everything else, generic:
-        | otherwise =
-            JsEq (JsGetProp constructor "name")
-                 (JsLit (JsStr (qname cons)))
+        | otherwise = forcedExp `JsInstanceOf` (UnQual (Ident ((qname cons) ++ "_RecConstr")))
   return [JsIf compareConstructorNames
                substmts
                []]
diff --git a/src/Language/Fay/Print.hs b/src/Language/Fay/Print.hs
--- a/src/Language/Fay/Print.hs
+++ b/src/Language/Fay/Print.hs
@@ -148,6 +148,8 @@
     printJS exp1 ++ " === " ++ printJS exp2
   printJS (JsGetProp exp prop) =
     printJS exp ++ "." ++ printJS prop
+  printJS (JsLookup exp1 exp2) =
+    printJS exp1 ++ "[" ++ printJS exp2 ++ "]"
   printJS (JsUpdateProp name prop expr) =
     (concat ["(",printJS name,".",printJS prop," = ",printJS expr,")"])
   printJS (JsInfix op x y) =
diff --git a/src/Language/Fay/Types.hs b/src/Language/Fay/Types.hs
--- a/src/Language/Fay/Types.hs
+++ b/src/Language/Fay/Types.hs
@@ -136,6 +136,7 @@
   | JsSequence [JsExp]
   | JsParen JsExp
   | JsGetProp JsExp JsName
+  | JsLookup JsExp JsExp
   | JsUpdateProp JsExp JsName JsExp
   | JsGetPropExtern JsExp JsName
   | JsUpdatePropExtern JsExp JsName JsExp
diff --git a/tests/16 b/tests/16
--- a/tests/16
+++ b/tests/16
@@ -1,1 +1,4 @@
 Hello!
+Hello!
+Hello!
+Hello!
diff --git a/tests/16.hs b/tests/16.hs
--- a/tests/16.hs
+++ b/tests/16.hs
@@ -1,7 +1,17 @@
-data Person = Person String String Int
+data Person1 = Person1 String String Int
+data Person2 = Person2 { fname :: String, sname :: String, age :: Int }
+data Person3 = Person3 { slot3 :: String, slot2 :: String, slot1 :: Int }
 
-main = print (case Person "Chris" "Done" 13 of
-                Person "Chris" "Done" 13 -> "Hello!")
+p1  = Person1 "Chris" "Done" 13
+p2  = Person2 "Chris" "Done" 13
+p2a = Person2 { fname = "Chris", sname = "Done", age = 13 }
+p3  = Person3 "Chris" "Done" 13
+
+main = do
+  print (case p1 of Person1 "Chris" "Done" 13 -> "Hello!")
+  print (case p2 of Person2 "Chris" "Done" 13 -> "Hello!")
+  print (case p2a of Person2 "Chris" "Done" 13 -> "Hello!")
+  print (case p3 of Person3 "Chris" "Done" 13 -> "Hello!")
 
 print :: String -> Fay ()
 print = ffi "console.log(%1)"
