
function cons(x, xs) {
   return [x, xs];
}

var head = attr(0);
var tail = attr(1);
var emptyList = null;

function reverseList(list){

   // js re-implementation of 3rd solution from:
   //    http://www.haskell.org/haskellwiki/99_questions/Solutions/5
   function reverseInner( list, reversed ) {
      if( !list ) {
         return reversed;
      }
      
      return reverseInner(tail(list), cons(head(list), reversed))
   }

   return reverseInner(list, emptyList);
}

function listAsArray(list){

   return foldR( function(arraySoFar, listItem){
      
      arraySoFar.unshift(listItem);
      return arraySoFar;
           
   }, [], list );
   
}

function map(fn, list) {

   return list
            ? cons(fn(head(list)), map(fn,tail(list)))
            : emptyList
            ;
}

/**
   @pram {Function} fn     (rightEval, curVal) -> result 
 */
function foldR(fn, startValue, list) {
      
   return list 
            ? fn(foldR(fn, startValue, tail(list)), head(list))
            : startValue
            ;
}

/* return true if the given function holds for every item in 
 * the list 
 */
function listEvery(fn, list) {
   
   return !list || 
          fn(head(list)) && listEvery(fn, tail(list));
}

/**
 * This doesn't make any sense if we're doing pure functional because it doesn't return
 * anything. Hence, this is only really useful for callbacks if fn has side-effects. 
 * 
 * @param fn
 * @param list
 */
function listEach(fn, list) {

   if( list ){  
      fn(head(list));
      listEvery(fn, tail(list));
   }
}

/* convert an array to a list */
function asList(array){

   var l = emptyList;

   for( var i = array.length ; i--; ) {
      l = cons(array[i], l);      
   }

   return l;   
}

var list = varArgs(asList);

@@ -24,22 +24,133 @@
 %0A   
-return %5Bx, xs%5D
+%0A   // Lists are all immutable. Object.freeze provides this in newer Javascript engines.%0A   return Object.freeze(%7Bh:x, t:xs%7D)
 ;%0A%7D%0A
@@ -170,9 +170,11 @@
 ttr(
-0
+'h'
 );%0Av
@@ -192,9 +192,11 @@
 ttr(
-1
+'t'
 );%0Av
@@ -221,264 +221,237 @@
 l;%0A%0A
-function reverseList(list)%7B%0A%0A   // js re-implementation of 3rd solution from:%0A   //    http://www.haskell.org/haskellwiki/99_questions/Solutions/5%0A   function reverseInner( list, reversed ) %7B%0A      if( !list ) %7B%0A         return reversed;%0A
+/** Converts an array to a list %0A * %0A *  asList(%5Ba,b,c%5D) = cons(a,cons(b,cons(c,emptyList))); %0A **/%0Afunction asList(array)%7B%0A%0A   var l = emptyList;%0A%0A   for( var i = array.length ; i--; ) %7B%0A      l = cons(array%5Bi%5D, l);
       
-%7D
 %0A   
-   %0A   
+%7D%0A%0A
    r
@@ -460,110 +460,196 @@
 urn 
-reverseInner(tail(list), cons(head(list), reversed))%0A   %7D%0A%0A   return reverseInner(list, emptyList);%0A%7D%0A
+l;   %0A%7D%0A%0A/**%0A * A varargs version of as List%0A * %0A *  asList(a,b,c) = cons(a,cons(b,cons(c,emptyList)));%0A */%0Avar list = varArgs(asList);%0A%0A/**%0A * Convert a list back to a js native array%0A */
 %0Afun
@@ -828,16 +828,55 @@
 %0A   %0A%7D%0A%0A
+/**%0A * Map a function over a list %0A */%0A
 function
@@ -1009,17 +1009,84 @@
 %7D%0A%0A/**%0A 
- 
+* foldR implementation. Reduce a list down to a single value.%0A * %0A *
  @pram %7B
@@ -1307,23 +1307,29 @@
  ;%0A%7D%0A%0A/*
- r
+* %0A * R
 eturn
+s
  true if
@@ -1380,24 +1380,41 @@
 %0A * the list
+, false otherwise
  %0A */%0Afuncti
@@ -1524,16 +1524,64 @@
 %0A%7D%0A%0A/**%0A
+ * Apply a function to every item in a list%0A * %0A
  * This 
@@ -1750,40 +1750,8 @@
 s. %0A
- * %0A * @param fn%0A * @param list%0A
  */%0A
@@ -1867,35 +1867,41 @@
 %0A%0A/*
- convert an array to
+*%0A * Reverse the order of
  a list
+%0A
  */%0A
@@ -1913,171 +1913,362 @@
 ion 
-asList(array)%7B%0A%0A   var l = emptyList;%0A%0A   for( var i = array.length ; i--; ) %7B%0A      l = cons(array%5Bi%5D, l);      %0A   %7D%0A%0A   return l;   %0A%7D%0A%0Avar list = varArgs(as
+reverseList(list)%7B%0A%0A   // js re-implementation of 3rd solution from:%0A   //    http://www.haskell.org/haskellwiki/99_questions/Solutions/5%0A   function reverseInner( list, reversed ) %7B%0A      if( !list ) %7B%0A         return reversed;%0A      %7D%0A      %0A      return reverseInner(tail(list), cons(head(list), reversed))%0A   %7D%0A%0A   return reverseInner(list, empty
 List);%0A
+%7D

recomment and re-order lists