diff --git a/libraries/prelude/prelude.purs b/libraries/prelude/prelude.purs
deleted file mode 100644
--- a/libraries/prelude/prelude.purs
+++ /dev/null
@@ -1,1064 +0,0 @@
-module Prelude where
-
-  flip :: forall a b c. (a -> b -> c) -> b -> a -> c
-  flip f b a = f a b
-
-  const :: forall a b. a -> b -> a
-  const a _ = a
-
-  infixr 9 >>>
-  infixr 9 <<<
-
-  class Category a where
-    id :: forall t. a t t
-    (<<<) :: forall b c d. a c d -> a b c -> a b d
-    (>>>) :: forall b c d. a b c -> a c d -> a b d
-
-  instance Category (->) where
-    id x = x
-    (<<<) f g x = f (g x)
-    (>>>) f g x = g (f x)
-
-  infixr 0 $
-  infixl 0 #
-
-  ($) :: forall a b. (a -> b) -> a -> b
-  ($) f x = f x
-
-  (#) :: forall a b. a -> (a -> b) -> b
-  (#) x f = f x
-
-  class Show a where
-    show :: a -> String
-
-  instance Show String where
-    show s = s
-
-  instance Show Boolean where
-    show true = "true"
-    show false = "false"
-
-  foreign import showNumber "function showNumber(n) {\
-                            \  return n.toString();\
-                            \}" :: Number -> String
-
-  instance Prelude.Show Number where
-    show = showNumber
-
-  class Read a where
-    read :: String -> a
-
-  instance Read String where
-    read s = s
-
-  instance Read Boolean where
-    read "true" = true
-    read _ = false
-
-  infixl 4 <$>
-
-  class Functor f where
-    (<$>) :: forall a b. (a -> b) -> f a -> f b
-
-  infixl 4 <*>
-
-  class Applicative f where
-    pure :: forall a. a -> f a
-    (<*>) :: forall a b. f (a -> b) -> f a -> f b
-
-  instance (Applicative f) => Functor f where
-    (<$>) f a = pure f <*> a
-
-  infixl 3 <|>
-
-  class Alternative f where
-    empty :: forall a. f a
-    (<|>) :: forall a. f a -> f a -> f a
-
-  infixl 1 >>=
-
-  class Monad m where
-    return :: forall a. a -> m a
-    (>>=) :: forall a b. m a -> (a -> m b) -> m b
-
-  instance (Monad m) => Applicative m where
-    pure = return
-    (<*>) f a = do
-      f' <- f
-      a' <- a
-      return (f' a')
-
-  infixl 7 *
-  infixl 7 /
-  infixl 7 %
-
-  infixl 6 -
-  infixl 6 +
-
-  class Num a where
-    (+) :: a -> a -> a
-    (-) :: a -> a -> a
-    (*) :: a -> a -> a
-    (/) :: a -> a -> a
-    (%) :: a -> a -> a
-    negate :: a -> a
-
-  foreign import numAdd "function numAdd(n1) {\
-                        \  return function(n2) {\
-                        \    return n1 + n2;\
-                        \  };\
-                        \}" :: Number -> Number -> Number
-
-  foreign import numSub "function numSub(n1) {\
-                        \  return function(n2) {\
-                        \    return n1 - n2;\
-                        \  };\
-                        \}" :: Number -> Number -> Number
-
-  foreign import numMul "function numMul(n1) {\
-                        \  return function(n2) {\
-                        \    return n1 * n2;\
-                        \  };\
-                        \}" :: Number -> Number -> Number
-
-  foreign import numDiv "function numDiv(n1) {\
-                        \  return function(n2) {\
-                        \    return n1 / n2;\
-                        \  };\
-                        \}" :: Number -> Number -> Number
-
-  foreign import numMod "function numMod(n1) {\
-                        \  return function(n2) {\
-                        \    return n1 % n2;\
-                        \  };\
-                        \}" :: Number -> Number -> Number
-
-  foreign import numNegate "function numNegate(n) {\
-                           \  return -n;\
-                           \}" :: Number -> Number
-
-  instance Num Number where
-    (+) = numAdd
-    (-) = numSub
-    (*) = numMul
-    (/) = numDiv
-    (%) = numMod
-    negate = numNegate
-
-  infixl 4 ==
-  infixl 4 /=
-
-  class Eq a where
-    (==) :: a -> a -> Boolean
-    (/=) :: a -> a -> Boolean
-
-  -- Referential equality
-  data Ref a = Ref a
-
-  foreign import refEq "function refEq(r1) {\
-                       \  return function(r2) {\
-                       \    return r1.value === r2.value;\
-                       \  };\
-                       \}" :: forall a. Ref a -> Ref a -> Boolean
-
-  foreign import refIneq "function refIneq(r1) {\
-                         \  return function(r2) {\
-                         \    return r1.value !== r2.value;\
-                         \  };\
-                         \}" :: forall a. Ref a -> Ref a -> Boolean
-
-  foreign import unsafeRefEq "function unsafeRefEq(r1) {\
-                             \  return function(r2) {\
-                             \    return r1 === r2;\
-                             \  };\
-                             \}" :: forall a. a -> a -> Boolean
-
-  foreign import unsafeRefIneq "function unsafeRefIneq(r1) {\
-                               \  return function(r2) {\
-                               \    return r1 !== r2;\
-                               \  };\
-                               \}" :: forall a. a -> a -> Boolean
-
-  instance Eq (Ref a) where
-    (==) = refEq
-    (/=) = refIneq
-
-  instance Eq String where
-    (==) = unsafeRefEq
-    (/=) = unsafeRefIneq
-
-  instance Eq Number where
-    (==) = unsafeRefEq
-    (/=) = unsafeRefIneq
-
-  instance Eq Boolean where
-    (==) = unsafeRefEq
-    (/=) = unsafeRefIneq
-
-  instance (Eq a) => Eq [a] where
-    (==) [] [] = true
-    (==) (x:xs) (y:ys) = x == y && xs == ys
-    (==) _ _ = false
-    (/=) xs ys = not (xs == ys)
-
-  infixl 4 <
-  infixl 4 >
-  infixl 4 <=
-  infixl 4 >=
-
-  class Ord a where
-    (<) :: a -> a -> Boolean
-    (>) :: a -> a -> Boolean
-    (<=) :: a -> a -> Boolean
-    (>=) :: a -> a -> Boolean
-
-  foreign import numLess "function numLess(n1) {\
-                         \  return function(n2) {\
-                         \    return n1 < n2;\
-                         \  };\
-                         \}" :: Number -> Number -> Boolean
-
-  foreign import numLessEq "function numLessEq(n1) {\
-                           \  return function(n2) {\
-                           \    return n1 <= n2;\
-                           \  };\
-                           \}" :: Number -> Number -> Boolean
-
-  foreign import numGreater "function numGreater(n1) {\
-                            \  return function(n2) {\
-                            \    return n1 > n2;\
-                            \  };\
-                            \}" :: Number -> Number -> Boolean
-
-  foreign import numGreaterEq "function numGreaterEq(n1) {\
-                              \  return function(n2) {\
-                              \    return n1 >= n2;\
-                              \  };\
-                              \}" :: Number -> Number -> Boolean
-
-  instance Ord Number where
-    (<) = numLess
-    (>) = numGreater
-    (<=) = numLessEq
-    (>=) = numGreaterEq
-
-  infixl 10 &
-  infixl 10 |
-  infixl 10 ^
-
-  class Bits b where
-    (&) :: b -> b -> b
-    (|) :: b -> b -> b
-    (^) :: b -> b -> b
-    shl :: b -> Number -> b
-    shr :: b -> Number -> b
-    zshr :: b -> Number -> b
-    complement :: b -> b
-
-  foreign import numShl "function numShl(n1) {\
-                        \  return function(n2) {\
-                        \    return n1 << n2;\
-                        \  };\
-                        \}" :: Number -> Number -> Number
-
-  foreign import numShr "function numShr(n1) {\
-                        \  return function(n2) {\
-                        \    return n1 >> n2;\
-                        \  };\
-                        \}" :: Number -> Number -> Number
-
-  foreign import numZshr "function numZshr(n1) {\
-                          \  return function(n2) {\
-                          \    return n1 >>> n2;\
-                          \  };\
-                          \}" :: Number -> Number -> Number
-
-  foreign import numAnd "function numAnd(n1) {\
-                        \  return function(n2) {\
-                        \    return n1 & n2;\
-                        \  };\
-                        \}" :: Number -> Number -> Number
-
-  foreign import numOr "function numOr(n1) {\
-                       \  return function(n2) {\
-                       \    return n1 | n2;\
-                       \  };\
-                       \}" :: Number -> Number -> Number
-
-  foreign import numXor "function numXor(n1) {\
-                        \  return function(n2) {\
-                        \    return n1 ^ n2;\
-                        \  };\
-                        \}" :: Number -> Number -> Number
-
-  foreign import numComplement "function numComplement(n) {\
-                               \  return ~n;\
-                               \}" :: Number -> Number
-
-  instance Bits Number where
-    (&) = numAnd
-    (|) = numOr
-    (^) = numXor
-    shl = numShl
-    shr = numShr
-    zshr = numZshr
-    complement = numComplement
-
-  infixl 8 !!
-
-  foreign import (!!) "function $bang$bang(xs) {\
-                      \  return function(n) {\
-                      \    return xs[n];\
-                      \  };\
-                      \}" :: forall a. [a] -> Number -> a
-
-  infixr 2 ||
-  infixr 3 &&
-
-  class BoolLike b where
-    (&&) :: b -> b -> b
-    (||) :: b -> b -> b
-    not :: b -> b
-
-  foreign import boolAnd "function boolAnd(b1) {\
-                         \  return function(b2) {\
-                         \    return b1 && b2;\
-                         \  };\
-                         \}"  :: Boolean -> Boolean -> Boolean
-
-  foreign import boolOr "function boolOr(b1) {\
-                        \  return function(b2) {\
-                        \    return b1 || b2;\
-                        \  };\
-                        \}" :: Boolean -> Boolean -> Boolean
-
-  foreign import boolNot "function boolNot(b) {\
-                         \  return !b;\
-                         \}" :: Boolean -> Boolean
-
-  instance BoolLike Boolean where
-    (&&) = boolAnd
-    (||) = boolOr
-    not = boolNot
-
-  infixr 5 ++
-
-  foreign import (++) "function $plus$plus(s1) {\
-                      \  return function(s2) {\
-                      \    return s1 + s2;\
-                      \  };\
-                      \}" :: String -> String -> String
-
-module Monoid where
-
-  import Prelude
-
-  infixr 6 <>
-
-  class Monoid m where
-    mempty :: m
-    (<>) :: m -> m -> m
-
-  instance Monoid String where
-    mempty = ""
-    (<>) = (++)
-
-  mconcat :: forall m. (Monoid m) => [m] -> m
-  mconcat [] = mempty
-  mconcat (m:ms) = m <> mconcat ms
-
-module Monad where
-
-  import Prelude
-  import Arrays
-
-  replicateM :: forall m a. (Monad m) => Number -> m a -> m [a]
-  replicateM 0 _ = return []
-  replicateM n m = do
-    a <- m
-    as <- replicateM (n - 1) m
-    return (a : as)
-
-  mapM :: forall m a b. (Monad m) => (a -> m b) -> [a] -> m [b]
-  mapM _ [] = return []
-  mapM f (a:as) = do
-    b <- f a
-    bs <- mapM f as
-    return (b : bs)
-
-  infixr 1 >=>
-  infixr 1 <=<
-
-  (>=>) :: forall m a b c. (Monad m) => (a -> m b) -> (b -> m c) -> a -> m c
-  (>=>) f g a = do
-    b <- f a
-    g b
-
-  (<=<) :: forall m a b c. (Monad m) => (b -> m c) -> (a -> m b) -> a -> m c
-  (<=<) = flip (>=>)
-
-  sequence :: forall m a. (Monad m) => [m a] -> m [a]
-  sequence [] = return []
-  sequence (m:ms) = do
-    a <- m
-    as <- sequence ms
-    return (a : as)
-
-  join :: forall m a. (Monad m) => m (m a) -> m a
-  join mm = do
-    m <- mm
-    m
-
-  foldM :: forall m a b. (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
-  foldM _ a [] = return a
-  foldM f a (b:bs) = f a b >>= \a' -> foldM f a' bs
-
-  when :: forall m. (Monad m) => Boolean -> m {} -> m {}
-  when true m = m
-  when false _ = return {}
-
-module Maybe where
-
-  import Prelude
-
-  data Maybe a = Nothing | Just a
-
-  maybe :: forall a b. b -> (a -> b) -> Maybe a -> b
-  maybe b _ Nothing = b
-  maybe _ f (Just a) = f a
-
-  fromMaybe :: forall a. a -> Maybe a -> a
-  fromMaybe a = maybe a (Prelude.id :: forall a. a -> a)
-
-  instance Prelude.Monad Maybe where
-    return = Just
-    (>>=) m f = maybe Nothing f m
-
-module Either where
-
-  data Either a b = Left a | Right b
-
-  either :: forall a b c. (a -> c) -> (b -> c) -> Either a b -> c
-  either f _ (Left a) = f a
-  either _ g (Right b) = g b
-
-  instance Prelude.Monad (Either e) where
-    return = Right
-    (>>=) = either (\e _ -> Left e) (\a f -> f a)
-
-module Arrays where
-
-  import Prelude
-  import Maybe
-
-  head :: forall a. [a] -> a
-  head (x : _) = x
-
-  headSafe :: forall a. [a] -> Maybe a
-  headSafe (x : _) = Just x
-  headSafe _ = Nothing
-
-  tail :: forall a. [a] -> [a]
-  tail (_ : xs) = xs
-
-  tailSafe :: forall a. [a] -> Maybe [a]
-  tailSafe (_ : xs) = Just xs
-  tailSafe _ = Nothing
-
-  map :: forall a b. (a -> b) -> [a] -> [b]
-  map _ [] = []
-  map f (x:xs) = f x : map f xs
-
-  foldr :: forall a b. (a -> b -> a) -> a -> [b] -> a
-  foldr f a (b : bs) = f (foldr f a bs) b
-  foldr _ a [] = a
-
-  foldl :: forall a b. (a -> b -> b) -> b -> [a] -> b
-  foldl _ b [] = b
-  foldl f b (a:as) = foldl f (f a b) as
-
-  foreign import length "function length(xs) { \
-                        \  return xs.length; \
-                        \}" :: forall a. [a] -> Number
-
-  foreign import indexOf "function indexOf(l) {\
-                         \  return function (e) {\
-                         \    return l.indexOf(e);\
-                         \  };\
-                         \}" :: forall a. [a] -> a -> Number
-
-  foreign import lastIndexOf "function lastIndexOf(l) {\
-                             \  return function (e) {\
-                             \    return l.lastIndexOf(e);\
-                             \  };\
-                             \}" :: forall a. [a] -> a -> Number
-
-  foreign import concat "function concat(l1) {\
-                        \  return function (l2) {\
-                        \    return l1.concat(l2);\
-                        \  };\
-                        \}" :: forall a. [a] -> [a] -> [a]
-
-  foreign import joinS "function joinS(l) {\
-                       \  return l.join();\
-                       \}" :: [String] -> String
-
-  foreign import joinWith "function joinWith(l) {\
-                          \  return function (s) {\
-                          \    return l.join(s);\
-                          \  };\
-                          \}" :: [String] -> String -> String
-
-  foreign import push "function push(l) {\
-                      \  return function (e) {\
-                      \    var l1 = l.slice();\
-                      \    l1.push(e); \
-                      \    return l1;\
-                      \  };\
-                      \}" :: forall a. [a] -> a -> [a]
-
-  foreign import reverse "function reverse(l) {\
-                         \  var l1 = l.slice();\
-                         \  l1.reverse(); \
-                         \  return l1;\
-                         \}" :: forall a. [a] -> [a]
-
-  foreign import shift "function shift(l) {\
-                       \  var l1 = l.slice();\
-                       \  l1.shift();\
-                       \  return l1;\
-                       \}" :: forall a. [a] -> [a]
-
-  foreign import slice "function slice(s) {\
-                       \  return function(e) {\
-                       \    return function (l) {\
-                       \      return l.slice(s, e);\
-                       \    };\
-                       \  };\
-                       \}" :: forall a. Number -> Number -> [a] -> [a]
-
-  foreign import sort "function sort(l) {\
-                      \  var l1 = l.slice();\
-                      \  l.sort();\
-                      \  return l1;\
-                      \}" :: forall a. [a] -> [a]
-
-  foreign import splice "function splice(s) {\
-                        \  return function(e) {\
-                        \    return function(l1) { \
-                        \      return function(l2) {\
-                        \        return l2.splice(s, e, l1);\
-                        \      }; \
-                        \    }; \
-                        \  };\
-                        \}":: forall a. Number -> Number -> [a] -> [a] -> [a]
-
-  infixr 6 :
-
-  (:) :: forall a. a -> [a] -> [a]
-  (:) a = concat [a]
-
-  singleton :: forall a. a -> [a]
-  singleton a = [a]
-
-  concatMap :: forall a b. [a] -> (a -> [b]) -> [b]
-  concatMap [] f = []
-  concatMap (a:as) f = f a `concat` concatMap as f
-
-  filter :: forall a. (a -> Boolean) -> [a] -> [a]
-  filter _ [] = []
-  filter p (x:xs) | p x = x : filter p xs
-  filter p (_:xs) = filter p xs
-
-  isEmpty :: forall a. [a] -> Boolean
-  isEmpty [] = true
-  isEmpty _ = false
-
-  range :: Number -> Number -> [Number]
-  range lo hi = {
-      var ns = [];
-      for (n <- lo until hi) {
-	ns = push ns n;
-      }
-      return ns;
-    }
-
-  zipWith :: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
-  zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
-  zipWith _ _ _ = []
-
-  any :: forall a. (a -> Boolean) -> [a] -> Boolean
-  any _ [] = false
-  any p (a:as) = p a || any p as
-
-  all :: forall a. (a -> Boolean) -> [a] -> Boolean
-  all _ [] = true
-  all p (a:as) = p a && all p as
-
-  instance (Prelude.Show a) => Prelude.Show [a] where
-    show [] = "[]"
-    show (x:xs) = show x ++ " : " ++ show xs
-
-  instance Prelude.Monad [] where
-    return = singleton
-    (>>=) = concatMap
-
-  instance Prelude.Alternative [] where
-    empty = []
-    (<|>) = concat
-
-module Tuples where
-
-  import Prelude
-  import Arrays
-
-  data Tuple a b = Tuple { fst :: a, snd :: b }
-
-  instance (Prelude.Show a, Prelude.Show b) => Prelude.Show (Tuple a b) where
-    show (Tuple { fst = a, snd = b }) = "Tuple(" ++ show a ++ ", " ++ show b ++ ")"
-
-  curry :: forall a b c. (Tuple a b -> c) -> a -> b -> c
-  curry f a b = f (tuple a b)
-
-  uncurry :: forall a b c. (a -> b -> c) -> Tuple a b -> c
-  uncurry f (Tuple t) = f t.fst t.snd
-
-  tuple :: forall a b. a -> b -> Tuple a b
-  tuple a b = Tuple { fst: a, snd: b }
-
-  zip :: forall a b. [a] -> [b] -> [Tuple a b]
-  zip = zipWith tuple
-
-  unzip :: forall a b. [Tuple a b] -> Tuple [a] [b]
-  unzip ((Tuple t):ts) = case unzip ts of
-    Tuple { fst = as, snd = bs } -> tuple (t.fst : as) (t.snd : bs)
-  unzip [] = tuple [] []
-
-module String where
-
-  foreign import lengthS "function lengthS(s) {\
-                         \  return s.length;\
-                         \}" :: String -> Number
-
-  foreign import charAt "function charAt(i) {\
-                        \  return function(s) {\
-                        \    return s.charAt(i); \
-                        \  };\
-                        \}" :: Number -> String -> String
-
-  foreign import indexOfS "function indexOfS(s1) {\
-                          \  return function(s2) {\
-                          \    return s2.indexOf(s2);\
-                          \  }; \
-                          \}" :: String -> String -> Number
-
-  foreign import lastIndexOfS "function lastIndexOfS(s1) {\
-                              \  return function(s2) {\
-                              \    return s2.lastIndexOf(s2);\
-                              \  };\
-                              \}" :: String -> String -> Number
-
-  foreign import localeCompare "function localeCompare(s1) {\
-                               \  return function(s2) { \
-                               \    return s1.localeCompare(s2);\
-                               \  };\
-                               \}" :: String -> String -> Number
-
-  foreign import replace "function replace(s1) {\
-                         \  return function(s2) {\
-                         \    return function(s3) {\
-                         \      return s3.replace(s1, s2);\
-                         \    };\
-                         \  };\
-                         \}" :: String -> String -> String -> String
-
-  foreign import sliceS "function sliceS(st) {\
-                        \  return function(e) {\
-                        \    return function(s) {\
-                        \      return s.slice(st, e);\
-                        \    };\
-                        \  };\
-                        \}" :: Number -> Number -> String -> String
-
-  foreign import split "function split(sep) {\
-                       \  return function(s) {\
-                       \    return s.split(s);\
-                       \  };\
-                       \}" :: String -> String -> [String]
-
-  foreign import substr "function substr(n1) {\
-                        \  return function(n2) {\
-                        \    return function(s) {\
-                        \      return s.substr(n1, n2);\
-                        \    };\
-                        \  };\
-                        \}" :: Number -> Number -> String -> String
-
-  foreign import substring "function substring(n1) {\
-                           \  return function(n2) {\
-                           \    return function(s) {\
-                           \      return s.substring(n1, n2);\
-                           \    };\
-                           \  };\
-                           \}" :: Number -> Number -> String -> String
-
-  foreign import toLower "function toLower(s) {\
-                         \  return s.toLower();\
-                         \}" :: String -> String
-
-  foreign import toUpper "function toUpper(s) {\
-                         \  return s.toUpper();\
-                         \}" :: String -> String
-
-  foreign import trim "function trim(s) {\
-                      \  return s.trim();\
-                      \}" :: String -> String
-
-module Regex where
-
-  foreign import data Regex :: *
-
-  foreign import regex "function regex(s1) {\
-                       \  return function(s2) {\
-                       \    return new Regex(s1, s2);\
-                       \  };\
-                       \}" :: String -> String -> Regex
-
-  foreign import test "function test(r) {\
-                      \  return function (s) { \
-                      \    return r.test(s);\
-                      \  };\
-                      \}" :: Regex -> String -> Boolean
-
-  foreign import match "function match(r) {\
-                       \  return function (s) {\
-                       \    return s.match(r); \
-                       \  };\
-                       \}" :: Regex -> String -> [String]
-
-  foreign import replaceR "function replaceR(r) {\
-                          \  return function(s1) {\
-                          \    return function(s2) { \
-                          \      return s2.replace(r, s1);\
-                          \    };\
-                          \  };\
-                          \}" :: Regex -> String -> String -> String
-
-  foreign import search "function search(r) {\
-                        \  return function (s) {\
-                        \    return s.search(r);\
-                        \  };\
-                        \}" :: Regex -> String -> Number
-
-module Global where
-
-  foreign import nan "var nan = NaN;" :: Number
-
-  foreign import infinity "var infinity = Infinity;" :: Number
-
-  foreign import toExponential "function toExponential(n) {\
-                               \  return n.toExponential();\
-                               \}" :: Number -> String
-
-  foreign import toFixed "function toFixed(d) {\
-                         \  return function(n) {\
-                         \    return n.toFixed(d);\
-                         \  };\
-                         \}" :: Number -> Number -> String
-
-  foreign import toPrecision "function toPrecision(d) {\
-                             \  return function(n) {\
-                             \    return n.toPrecision(d);\
-                             \  };\
-                             \}" :: Number -> Number -> String
-
-  foreign import isFinite :: Number -> Boolean
-
-  foreign import parseFloat :: String -> Number
-
-  foreign import parseInt :: String -> Number
-
-  foreign import encodeURIComponent :: String -> String
-
-  foreign import decodeURIComponent :: String -> String
-
-  foreign import encodeURI :: String -> String
-
-  foreign import decodeURI :: String -> String
-
-  foreign import isNaN :: Number -> Boolean
-
-module Math where
-
-  foreign import abs "function abs(n){\
-                     \  return Math.abs(n);\
-                     \}" :: Number -> Number
-
-  foreign import acos "function acos(n){\
-                      \  return Math.acos(n);\
-                      \}" :: Number -> Number
-
-  foreign import asin "function asin(n){\
-                      \  return Math.asin(n);\
-                      \}" :: Number -> Number
-
-  foreign import atan "function atan(n){\
-                      \  return Math.atan(n);\
-                      \}" :: Number -> Number
-
-  foreign import atan2 "function atan2(y){\
-                       \  return function (x) {\
-                       \    return Math.atan2(y, x);\
-                       \  };\
-                       \}" :: Number -> Number -> Number
-
-  foreign import aceil "function aceil(n){\
-                       \  return Math.aceil(n);\
-                       \}" :: Number -> Number
-
-  foreign import cos "function cos(n){\
-                     \  return Math.cos(n);\
-                     \}" :: Number -> Number
-
-  foreign import exp "function exp(n){\
-                     \  return Math.exp(n);\
-                     \}" :: Number -> Number
-
-  foreign import floor "function floor(n){\
-                       \  return Math.floor(n);\
-                       \}" :: Number -> Number
-
-  foreign import log "function log(n){\
-                     \  return Math.log(n);\
-                     \}" :: Number -> Number
-
-  foreign import max "function max(n){\
-                     \  return Math.max(n);\
-                     \}" :: Number -> Number
-
-  foreign import min "function min(n){\
-                     \  return Math.min(n);\
-                     \}" :: Number -> Number
-
-  foreign import pow "function pow(n){\
-                     \  return Math.pow(n);\
-                     \}" :: Number -> Number
-
-  foreign import round "function round(n){\
-                       \  return Math.round(n);\
-                       \}" :: Number -> Number
-
-  foreign import sin "function sin(n){\
-                     \  return Math.sin(n);\
-                     \}" :: Number -> Number
-
-  foreign import sqrt "function sqrt(n){\
-                      \  return Math.sqrt(n);\
-                      \}" :: Number -> Number
-
-  foreign import tan "function tan(n){\
-                     \  return Math.tan(n);\
-                     \}" :: Number -> Number
-
-module Eff where
-
-  foreign import data Eff :: # ! -> * -> *
-
-  foreign import retEff "function retEff(a) { \
-                        \  return function() { \
-                        \    return a; \
-                        \  }; \
-                        \}" :: forall e a. a -> Eff e a
-
-  foreign import bindEff "function bindEff(a) { \
-                         \  return function(f) { \
-                         \    return function() { \
-                         \      return f(a())(); \
-                         \    }; \
-                         \  }; \
-                         \}" :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
-
-  type Pure a = forall e. Eff e a
-
-  foreign import runPure "function runPure(f) { \
-                         \  return f(); \
-                         \}" :: forall a. Pure a -> a
-
-  instance Prelude.Monad (Eff e) where
-    return = retEff
-    (>>=) = bindEff
-
-  foreign import untilE "function untilE(f) {\
-			\  return function() {\
-			\    while (!f()) { }\
-			\    return {};\
-			\  };\
-                        \}" :: forall e. Eff e Boolean -> Eff e {}
-
-  foreign import whileE "function whileE(f) {\
-			\  return function(a) {\
-			\    return function() {\
-			\      while (f()) {\
-                        \        a();\
-                        \      }\
-			\      return {};\
-                        \    };\
-                        \  };\
-                        \}" :: forall e. Eff e Boolean -> Eff e {} -> Eff e {}
-
-  foreign import forE "function forE(lo) {\
-	              \  return function(hi) {\
-	              \    return function(f) {\
-	              \      return function() {\
-	              \        for (var i = lo; i < hi; i++) {\
-		      \          f(i)();\
-                      \        }\
-                      \      };\
-                      \    };\
-                      \  };\
-                      \}" :: forall e. Number -> Number -> (Number -> Eff e {}) -> Eff e {}
-
-
-  foreign import foreachE "function foreachE(as) {\
-	                  \  return function(f) {\
-	                  \    for (var i = 0; i < as.length; i++) {\
-		          \      f(as[i])();\
-                          \    }\
-                          \  };\
-                          \}" :: forall e a. [a] -> (a -> Eff e {}) -> Eff e {}
-
-
-module Random where
-
-  import Eff
-
-  foreign import data Random :: !
-
-  foreign import random "function random() {\
-                        \  return Math.random();\
-                        \}" :: forall e. Eff (random :: Random | e) Number
-
-module Errors where
-
-  import Eff
-
-  foreign import data Error :: * -> !
-
-  foreign import throwError "function throwError(e) { \
-                            \  return function() { \
-                            \    throw e; \
-                            \  }; \
-                            \}" :: forall a e r. e -> Eff (err :: Error e | r) a
-
-  foreign import catchError "function catchError(c) { \
-                            \  return function(t) { \
-                            \    return function() { \
-                            \      try { \
-                            \        return t(); \
-                            \      } catch(e) { \
-                            \        return c(e)(); \
-                            \      }\
-                            \    }; \
-                            \  }; \
-                            \}" :: forall e r a. (e -> Eff r a) -> Eff (err :: Error e | r) a -> Eff r a
-
-module IORef where
-
-  import Eff
-
-  foreign import data Ref :: !
-
-  foreign import data IORef :: * -> *
-
-  foreign import newIORef "function newIORef(val) {\
-                          \  return function () {\
-                          \    return { value: val };\
-                          \  };\
-                          \}" :: forall s r. s -> Eff (ref :: Ref | r) (IORef s)
-
-  foreign import readIORef "function readIORef(ref) {\
-                           \  return function() {\
-                           \    return ref.value;\
-                           \  };\
-                           \}" :: forall s r. IORef s -> Eff (ref :: Ref | r) s
-
-
-  foreign import modifyIORef "function modifyIORef(ref) {\
-                             \  return function(f) {\
-                             \    return function() {\
-                             \      ref.value = f(ref.value);\
-                             \      return {};\
-                             \    };\
-                             \  };\
-                             \}" :: forall s r. IORef s -> (s -> s) -> Eff (ref :: Ref | r) {}
-
-  foreign import writeIORef "function writeIORef(ref) {\
-                            \  return function(val) {\
-                            \    return function() {\
-                            \      ref.value = val;\
-                            \      return {};\
-                            \    };\
-                            \  };\
-                            \}" :: forall s r. IORef s -> s -> Eff (ref :: Ref | r) {}
-
-  foreign import unsafeRunIORef "function unsafeRunIORef(f) {\
-                                \  return f;\
-                                \}" :: forall eff a. Eff (ref :: Ref | eff) a -> Eff eff a
-
-module Trace where
-
-  import Prelude
-  import Eff
-
-  foreign import data Trace :: !
-
-  foreign import trace "function trace(s) { \
-                       \  return function() { \
-                       \    console.log(s); \
-                       \    return {}; \
-                       \  }; \
-                       \}" :: forall r. String -> Eff (trace :: Trace | r) {}
-
-  print :: forall a r. (Prelude.Show a) => a -> Eff (trace :: Trace | r) {}
-  print o = trace (show o)
-
-module ST where
-
-  import Eff
-
-  foreign import data ST :: * -> !
-
-  foreign import data STRef :: * -> * -> *
-
-  foreign import newSTRef "function newSTRef(val) {\
-                          \  return function () {\
-                          \    return { value: val };\
-                          \  };\
-                          \}" :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
-
-  foreign import readSTRef "function readSTRef(ref) {\
-                           \  return function() {\
-                           \    return ref.value;\
-                           \  };\
-                           \}" :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
-
-  foreign import modifySTRef "function modifySTRef(ref) {\
-                             \  return function(f) {\
-                             \    return function() {\
-                             \      ref.value = f(ref.value);\
-                             \    };\
-                             \  };\
-                             \}" :: forall a h r. STRef h a -> (a -> a) -> Eff (st :: ST h | r) {}
-
-  foreign import writeSTRef "function writeSTRef(ref) {\
-                            \  return function(a) {\
-                            \    return function() {\
-                            \      ref.value = a;\
-                            \    };\
-                            \  };\
-                            \}" :: forall a h r. STRef h a -> a -> Eff (st :: ST h | r) {}
-
-  foreign import runST "function runST(f) {\
-                       \  return f;\
-                       \}" :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
-
diff --git a/prelude/prelude.purs b/prelude/prelude.purs
new file mode 100644
--- /dev/null
+++ b/prelude/prelude.purs
@@ -0,0 +1,1064 @@
+module Prelude where
+
+  flip :: forall a b c. (a -> b -> c) -> b -> a -> c
+  flip f b a = f a b
+
+  const :: forall a b. a -> b -> a
+  const a _ = a
+
+  infixr 9 >>>
+  infixr 9 <<<
+
+  class Category a where
+    id :: forall t. a t t
+    (<<<) :: forall b c d. a c d -> a b c -> a b d
+    (>>>) :: forall b c d. a b c -> a c d -> a b d
+
+  instance Category (->) where
+    id x = x
+    (<<<) f g x = f (g x)
+    (>>>) f g x = g (f x)
+
+  infixr 0 $
+  infixl 0 #
+
+  ($) :: forall a b. (a -> b) -> a -> b
+  ($) f x = f x
+
+  (#) :: forall a b. a -> (a -> b) -> b
+  (#) x f = f x
+
+  class Show a where
+    show :: a -> String
+
+  instance Show String where
+    show s = s
+
+  instance Show Boolean where
+    show true = "true"
+    show false = "false"
+
+  foreign import showNumber "function showNumber(n) {\
+                            \  return n.toString();\
+                            \}" :: Number -> String
+
+  instance Prelude.Show Number where
+    show = showNumber
+
+  class Read a where
+    read :: String -> a
+
+  instance Read String where
+    read s = s
+
+  instance Read Boolean where
+    read "true" = true
+    read _ = false
+
+  infixl 4 <$>
+
+  class Functor f where
+    (<$>) :: forall a b. (a -> b) -> f a -> f b
+
+  infixl 4 <*>
+
+  class Applicative f where
+    pure :: forall a. a -> f a
+    (<*>) :: forall a b. f (a -> b) -> f a -> f b
+
+  instance (Applicative f) => Functor f where
+    (<$>) f a = pure f <*> a
+
+  infixl 3 <|>
+
+  class Alternative f where
+    empty :: forall a. f a
+    (<|>) :: forall a. f a -> f a -> f a
+
+  infixl 1 >>=
+
+  class Monad m where
+    return :: forall a. a -> m a
+    (>>=) :: forall a b. m a -> (a -> m b) -> m b
+
+  instance (Monad m) => Applicative m where
+    pure = return
+    (<*>) f a = do
+      f' <- f
+      a' <- a
+      return (f' a')
+
+  infixl 7 *
+  infixl 7 /
+  infixl 7 %
+
+  infixl 6 -
+  infixl 6 +
+
+  class Num a where
+    (+) :: a -> a -> a
+    (-) :: a -> a -> a
+    (*) :: a -> a -> a
+    (/) :: a -> a -> a
+    (%) :: a -> a -> a
+    negate :: a -> a
+
+  foreign import numAdd "function numAdd(n1) {\
+                        \  return function(n2) {\
+                        \    return n1 + n2;\
+                        \  };\
+                        \}" :: Number -> Number -> Number
+
+  foreign import numSub "function numSub(n1) {\
+                        \  return function(n2) {\
+                        \    return n1 - n2;\
+                        \  };\
+                        \}" :: Number -> Number -> Number
+
+  foreign import numMul "function numMul(n1) {\
+                        \  return function(n2) {\
+                        \    return n1 * n2;\
+                        \  };\
+                        \}" :: Number -> Number -> Number
+
+  foreign import numDiv "function numDiv(n1) {\
+                        \  return function(n2) {\
+                        \    return n1 / n2;\
+                        \  };\
+                        \}" :: Number -> Number -> Number
+
+  foreign import numMod "function numMod(n1) {\
+                        \  return function(n2) {\
+                        \    return n1 % n2;\
+                        \  };\
+                        \}" :: Number -> Number -> Number
+
+  foreign import numNegate "function numNegate(n) {\
+                           \  return -n;\
+                           \}" :: Number -> Number
+
+  instance Num Number where
+    (+) = numAdd
+    (-) = numSub
+    (*) = numMul
+    (/) = numDiv
+    (%) = numMod
+    negate = numNegate
+
+  infixl 4 ==
+  infixl 4 /=
+
+  class Eq a where
+    (==) :: a -> a -> Boolean
+    (/=) :: a -> a -> Boolean
+
+  -- Referential equality
+  data Ref a = Ref a
+
+  foreign import refEq "function refEq(r1) {\
+                       \  return function(r2) {\
+                       \    return r1.value === r2.value;\
+                       \  };\
+                       \}" :: forall a. Ref a -> Ref a -> Boolean
+
+  foreign import refIneq "function refIneq(r1) {\
+                         \  return function(r2) {\
+                         \    return r1.value !== r2.value;\
+                         \  };\
+                         \}" :: forall a. Ref a -> Ref a -> Boolean
+
+  foreign import unsafeRefEq "function unsafeRefEq(r1) {\
+                             \  return function(r2) {\
+                             \    return r1 === r2;\
+                             \  };\
+                             \}" :: forall a. a -> a -> Boolean
+
+  foreign import unsafeRefIneq "function unsafeRefIneq(r1) {\
+                               \  return function(r2) {\
+                               \    return r1 !== r2;\
+                               \  };\
+                               \}" :: forall a. a -> a -> Boolean
+
+  instance Eq (Ref a) where
+    (==) = refEq
+    (/=) = refIneq
+
+  instance Eq String where
+    (==) = unsafeRefEq
+    (/=) = unsafeRefIneq
+
+  instance Eq Number where
+    (==) = unsafeRefEq
+    (/=) = unsafeRefIneq
+
+  instance Eq Boolean where
+    (==) = unsafeRefEq
+    (/=) = unsafeRefIneq
+
+  instance (Eq a) => Eq [a] where
+    (==) [] [] = true
+    (==) (x:xs) (y:ys) = x == y && xs == ys
+    (==) _ _ = false
+    (/=) xs ys = not (xs == ys)
+
+  infixl 4 <
+  infixl 4 >
+  infixl 4 <=
+  infixl 4 >=
+
+  class Ord a where
+    (<) :: a -> a -> Boolean
+    (>) :: a -> a -> Boolean
+    (<=) :: a -> a -> Boolean
+    (>=) :: a -> a -> Boolean
+
+  foreign import numLess "function numLess(n1) {\
+                         \  return function(n2) {\
+                         \    return n1 < n2;\
+                         \  };\
+                         \}" :: Number -> Number -> Boolean
+
+  foreign import numLessEq "function numLessEq(n1) {\
+                           \  return function(n2) {\
+                           \    return n1 <= n2;\
+                           \  };\
+                           \}" :: Number -> Number -> Boolean
+
+  foreign import numGreater "function numGreater(n1) {\
+                            \  return function(n2) {\
+                            \    return n1 > n2;\
+                            \  };\
+                            \}" :: Number -> Number -> Boolean
+
+  foreign import numGreaterEq "function numGreaterEq(n1) {\
+                              \  return function(n2) {\
+                              \    return n1 >= n2;\
+                              \  };\
+                              \}" :: Number -> Number -> Boolean
+
+  instance Ord Number where
+    (<) = numLess
+    (>) = numGreater
+    (<=) = numLessEq
+    (>=) = numGreaterEq
+
+  infixl 10 &
+  infixl 10 |
+  infixl 10 ^
+
+  class Bits b where
+    (&) :: b -> b -> b
+    (|) :: b -> b -> b
+    (^) :: b -> b -> b
+    shl :: b -> Number -> b
+    shr :: b -> Number -> b
+    zshr :: b -> Number -> b
+    complement :: b -> b
+
+  foreign import numShl "function numShl(n1) {\
+                        \  return function(n2) {\
+                        \    return n1 << n2;\
+                        \  };\
+                        \}" :: Number -> Number -> Number
+
+  foreign import numShr "function numShr(n1) {\
+                        \  return function(n2) {\
+                        \    return n1 >> n2;\
+                        \  };\
+                        \}" :: Number -> Number -> Number
+
+  foreign import numZshr "function numZshr(n1) {\
+                          \  return function(n2) {\
+                          \    return n1 >>> n2;\
+                          \  };\
+                          \}" :: Number -> Number -> Number
+
+  foreign import numAnd "function numAnd(n1) {\
+                        \  return function(n2) {\
+                        \    return n1 & n2;\
+                        \  };\
+                        \}" :: Number -> Number -> Number
+
+  foreign import numOr "function numOr(n1) {\
+                       \  return function(n2) {\
+                       \    return n1 | n2;\
+                       \  };\
+                       \}" :: Number -> Number -> Number
+
+  foreign import numXor "function numXor(n1) {\
+                        \  return function(n2) {\
+                        \    return n1 ^ n2;\
+                        \  };\
+                        \}" :: Number -> Number -> Number
+
+  foreign import numComplement "function numComplement(n) {\
+                               \  return ~n;\
+                               \}" :: Number -> Number
+
+  instance Bits Number where
+    (&) = numAnd
+    (|) = numOr
+    (^) = numXor
+    shl = numShl
+    shr = numShr
+    zshr = numZshr
+    complement = numComplement
+
+  infixl 8 !!
+
+  foreign import (!!) "function $bang$bang(xs) {\
+                      \  return function(n) {\
+                      \    return xs[n];\
+                      \  };\
+                      \}" :: forall a. [a] -> Number -> a
+
+  infixr 2 ||
+  infixr 3 &&
+
+  class BoolLike b where
+    (&&) :: b -> b -> b
+    (||) :: b -> b -> b
+    not :: b -> b
+
+  foreign import boolAnd "function boolAnd(b1) {\
+                         \  return function(b2) {\
+                         \    return b1 && b2;\
+                         \  };\
+                         \}"  :: Boolean -> Boolean -> Boolean
+
+  foreign import boolOr "function boolOr(b1) {\
+                        \  return function(b2) {\
+                        \    return b1 || b2;\
+                        \  };\
+                        \}" :: Boolean -> Boolean -> Boolean
+
+  foreign import boolNot "function boolNot(b) {\
+                         \  return !b;\
+                         \}" :: Boolean -> Boolean
+
+  instance BoolLike Boolean where
+    (&&) = boolAnd
+    (||) = boolOr
+    not = boolNot
+
+  infixr 5 ++
+
+  foreign import (++) "function $plus$plus(s1) {\
+                      \  return function(s2) {\
+                      \    return s1 + s2;\
+                      \  };\
+                      \}" :: String -> String -> String
+
+module Monoid where
+
+  import Prelude
+
+  infixr 6 <>
+
+  class Monoid m where
+    mempty :: m
+    (<>) :: m -> m -> m
+
+  instance Monoid String where
+    mempty = ""
+    (<>) = (++)
+
+  mconcat :: forall m. (Monoid m) => [m] -> m
+  mconcat [] = mempty
+  mconcat (m:ms) = m <> mconcat ms
+
+module Monad where
+
+  import Prelude
+  import Arrays
+
+  replicateM :: forall m a. (Monad m) => Number -> m a -> m [a]
+  replicateM 0 _ = return []
+  replicateM n m = do
+    a <- m
+    as <- replicateM (n - 1) m
+    return (a : as)
+
+  mapM :: forall m a b. (Monad m) => (a -> m b) -> [a] -> m [b]
+  mapM _ [] = return []
+  mapM f (a:as) = do
+    b <- f a
+    bs <- mapM f as
+    return (b : bs)
+
+  infixr 1 >=>
+  infixr 1 <=<
+
+  (>=>) :: forall m a b c. (Monad m) => (a -> m b) -> (b -> m c) -> a -> m c
+  (>=>) f g a = do
+    b <- f a
+    g b
+
+  (<=<) :: forall m a b c. (Monad m) => (b -> m c) -> (a -> m b) -> a -> m c
+  (<=<) = flip (>=>)
+
+  sequence :: forall m a. (Monad m) => [m a] -> m [a]
+  sequence [] = return []
+  sequence (m:ms) = do
+    a <- m
+    as <- sequence ms
+    return (a : as)
+
+  join :: forall m a. (Monad m) => m (m a) -> m a
+  join mm = do
+    m <- mm
+    m
+
+  foldM :: forall m a b. (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
+  foldM _ a [] = return a
+  foldM f a (b:bs) = f a b >>= \a' -> foldM f a' bs
+
+  when :: forall m. (Monad m) => Boolean -> m {} -> m {}
+  when true m = m
+  when false _ = return {}
+
+module Maybe where
+
+  import Prelude
+
+  data Maybe a = Nothing | Just a
+
+  maybe :: forall a b. b -> (a -> b) -> Maybe a -> b
+  maybe b _ Nothing = b
+  maybe _ f (Just a) = f a
+
+  fromMaybe :: forall a. a -> Maybe a -> a
+  fromMaybe a = maybe a (Prelude.id :: forall a. a -> a)
+
+  instance Prelude.Monad Maybe where
+    return = Just
+    (>>=) m f = maybe Nothing f m
+
+module Either where
+
+  data Either a b = Left a | Right b
+
+  either :: forall a b c. (a -> c) -> (b -> c) -> Either a b -> c
+  either f _ (Left a) = f a
+  either _ g (Right b) = g b
+
+  instance Prelude.Monad (Either e) where
+    return = Right
+    (>>=) = either (\e _ -> Left e) (\a f -> f a)
+
+module Arrays where
+
+  import Prelude
+  import Maybe
+
+  head :: forall a. [a] -> a
+  head (x : _) = x
+
+  headSafe :: forall a. [a] -> Maybe a
+  headSafe (x : _) = Just x
+  headSafe _ = Nothing
+
+  tail :: forall a. [a] -> [a]
+  tail (_ : xs) = xs
+
+  tailSafe :: forall a. [a] -> Maybe [a]
+  tailSafe (_ : xs) = Just xs
+  tailSafe _ = Nothing
+
+  map :: forall a b. (a -> b) -> [a] -> [b]
+  map _ [] = []
+  map f (x:xs) = f x : map f xs
+
+  foldr :: forall a b. (a -> b -> a) -> a -> [b] -> a
+  foldr f a (b : bs) = f (foldr f a bs) b
+  foldr _ a [] = a
+
+  foldl :: forall a b. (a -> b -> b) -> b -> [a] -> b
+  foldl _ b [] = b
+  foldl f b (a:as) = foldl f (f a b) as
+
+  foreign import length "function length(xs) { \
+                        \  return xs.length; \
+                        \}" :: forall a. [a] -> Number
+
+  foreign import indexOf "function indexOf(l) {\
+                         \  return function (e) {\
+                         \    return l.indexOf(e);\
+                         \  };\
+                         \}" :: forall a. [a] -> a -> Number
+
+  foreign import lastIndexOf "function lastIndexOf(l) {\
+                             \  return function (e) {\
+                             \    return l.lastIndexOf(e);\
+                             \  };\
+                             \}" :: forall a. [a] -> a -> Number
+
+  foreign import concat "function concat(l1) {\
+                        \  return function (l2) {\
+                        \    return l1.concat(l2);\
+                        \  };\
+                        \}" :: forall a. [a] -> [a] -> [a]
+
+  foreign import joinS "function joinS(l) {\
+                       \  return l.join();\
+                       \}" :: [String] -> String
+
+  foreign import joinWith "function joinWith(l) {\
+                          \  return function (s) {\
+                          \    return l.join(s);\
+                          \  };\
+                          \}" :: [String] -> String -> String
+
+  foreign import push "function push(l) {\
+                      \  return function (e) {\
+                      \    var l1 = l.slice();\
+                      \    l1.push(e); \
+                      \    return l1;\
+                      \  };\
+                      \}" :: forall a. [a] -> a -> [a]
+
+  foreign import reverse "function reverse(l) {\
+                         \  var l1 = l.slice();\
+                         \  l1.reverse(); \
+                         \  return l1;\
+                         \}" :: forall a. [a] -> [a]
+
+  foreign import shift "function shift(l) {\
+                       \  var l1 = l.slice();\
+                       \  l1.shift();\
+                       \  return l1;\
+                       \}" :: forall a. [a] -> [a]
+
+  foreign import slice "function slice(s) {\
+                       \  return function(e) {\
+                       \    return function (l) {\
+                       \      return l.slice(s, e);\
+                       \    };\
+                       \  };\
+                       \}" :: forall a. Number -> Number -> [a] -> [a]
+
+  foreign import sort "function sort(l) {\
+                      \  var l1 = l.slice();\
+                      \  l.sort();\
+                      \  return l1;\
+                      \}" :: forall a. [a] -> [a]
+
+  foreign import splice "function splice(s) {\
+                        \  return function(e) {\
+                        \    return function(l1) { \
+                        \      return function(l2) {\
+                        \        return l2.splice(s, e, l1);\
+                        \      }; \
+                        \    }; \
+                        \  };\
+                        \}":: forall a. Number -> Number -> [a] -> [a] -> [a]
+
+  infixr 6 :
+
+  (:) :: forall a. a -> [a] -> [a]
+  (:) a = concat [a]
+
+  singleton :: forall a. a -> [a]
+  singleton a = [a]
+
+  concatMap :: forall a b. [a] -> (a -> [b]) -> [b]
+  concatMap [] f = []
+  concatMap (a:as) f = f a `concat` concatMap as f
+
+  filter :: forall a. (a -> Boolean) -> [a] -> [a]
+  filter _ [] = []
+  filter p (x:xs) | p x = x : filter p xs
+  filter p (_:xs) = filter p xs
+
+  isEmpty :: forall a. [a] -> Boolean
+  isEmpty [] = true
+  isEmpty _ = false
+
+  range :: Number -> Number -> [Number]
+  range lo hi = {
+      var ns = [];
+      for (n <- lo until hi) {
+	ns = push ns n;
+      }
+      return ns;
+    }
+
+  zipWith :: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
+  zipWith f (a:as) (b:bs) = f a b : zipWith f as bs
+  zipWith _ _ _ = []
+
+  any :: forall a. (a -> Boolean) -> [a] -> Boolean
+  any _ [] = false
+  any p (a:as) = p a || any p as
+
+  all :: forall a. (a -> Boolean) -> [a] -> Boolean
+  all _ [] = true
+  all p (a:as) = p a && all p as
+
+  instance (Prelude.Show a) => Prelude.Show [a] where
+    show [] = "[]"
+    show (x:xs) = show x ++ " : " ++ show xs
+
+  instance Prelude.Monad [] where
+    return = singleton
+    (>>=) = concatMap
+
+  instance Prelude.Alternative [] where
+    empty = []
+    (<|>) = concat
+
+module Tuples where
+
+  import Prelude
+  import Arrays
+
+  data Tuple a b = Tuple { fst :: a, snd :: b }
+
+  instance (Prelude.Show a, Prelude.Show b) => Prelude.Show (Tuple a b) where
+    show (Tuple { fst = a, snd = b }) = "Tuple(" ++ show a ++ ", " ++ show b ++ ")"
+
+  curry :: forall a b c. (Tuple a b -> c) -> a -> b -> c
+  curry f a b = f (tuple a b)
+
+  uncurry :: forall a b c. (a -> b -> c) -> Tuple a b -> c
+  uncurry f (Tuple t) = f t.fst t.snd
+
+  tuple :: forall a b. a -> b -> Tuple a b
+  tuple a b = Tuple { fst: a, snd: b }
+
+  zip :: forall a b. [a] -> [b] -> [Tuple a b]
+  zip = zipWith tuple
+
+  unzip :: forall a b. [Tuple a b] -> Tuple [a] [b]
+  unzip ((Tuple t):ts) = case unzip ts of
+    Tuple { fst = as, snd = bs } -> tuple (t.fst : as) (t.snd : bs)
+  unzip [] = tuple [] []
+
+module String where
+
+  foreign import lengthS "function lengthS(s) {\
+                         \  return s.length;\
+                         \}" :: String -> Number
+
+  foreign import charAt "function charAt(i) {\
+                        \  return function(s) {\
+                        \    return s.charAt(i); \
+                        \  };\
+                        \}" :: Number -> String -> String
+
+  foreign import indexOfS "function indexOfS(s1) {\
+                          \  return function(s2) {\
+                          \    return s2.indexOf(s2);\
+                          \  }; \
+                          \}" :: String -> String -> Number
+
+  foreign import lastIndexOfS "function lastIndexOfS(s1) {\
+                              \  return function(s2) {\
+                              \    return s2.lastIndexOf(s2);\
+                              \  };\
+                              \}" :: String -> String -> Number
+
+  foreign import localeCompare "function localeCompare(s1) {\
+                               \  return function(s2) { \
+                               \    return s1.localeCompare(s2);\
+                               \  };\
+                               \}" :: String -> String -> Number
+
+  foreign import replace "function replace(s1) {\
+                         \  return function(s2) {\
+                         \    return function(s3) {\
+                         \      return s3.replace(s1, s2);\
+                         \    };\
+                         \  };\
+                         \}" :: String -> String -> String -> String
+
+  foreign import sliceS "function sliceS(st) {\
+                        \  return function(e) {\
+                        \    return function(s) {\
+                        \      return s.slice(st, e);\
+                        \    };\
+                        \  };\
+                        \}" :: Number -> Number -> String -> String
+
+  foreign import split "function split(sep) {\
+                       \  return function(s) {\
+                       \    return s.split(s);\
+                       \  };\
+                       \}" :: String -> String -> [String]
+
+  foreign import substr "function substr(n1) {\
+                        \  return function(n2) {\
+                        \    return function(s) {\
+                        \      return s.substr(n1, n2);\
+                        \    };\
+                        \  };\
+                        \}" :: Number -> Number -> String -> String
+
+  foreign import substring "function substring(n1) {\
+                           \  return function(n2) {\
+                           \    return function(s) {\
+                           \      return s.substring(n1, n2);\
+                           \    };\
+                           \  };\
+                           \}" :: Number -> Number -> String -> String
+
+  foreign import toLower "function toLower(s) {\
+                         \  return s.toLower();\
+                         \}" :: String -> String
+
+  foreign import toUpper "function toUpper(s) {\
+                         \  return s.toUpper();\
+                         \}" :: String -> String
+
+  foreign import trim "function trim(s) {\
+                      \  return s.trim();\
+                      \}" :: String -> String
+
+module Regex where
+
+  foreign import data Regex :: *
+
+  foreign import regex "function regex(s1) {\
+                       \  return function(s2) {\
+                       \    return new Regex(s1, s2);\
+                       \  };\
+                       \}" :: String -> String -> Regex
+
+  foreign import test "function test(r) {\
+                      \  return function (s) { \
+                      \    return r.test(s);\
+                      \  };\
+                      \}" :: Regex -> String -> Boolean
+
+  foreign import match "function match(r) {\
+                       \  return function (s) {\
+                       \    return s.match(r); \
+                       \  };\
+                       \}" :: Regex -> String -> [String]
+
+  foreign import replaceR "function replaceR(r) {\
+                          \  return function(s1) {\
+                          \    return function(s2) { \
+                          \      return s2.replace(r, s1);\
+                          \    };\
+                          \  };\
+                          \}" :: Regex -> String -> String -> String
+
+  foreign import search "function search(r) {\
+                        \  return function (s) {\
+                        \    return s.search(r);\
+                        \  };\
+                        \}" :: Regex -> String -> Number
+
+module Global where
+
+  foreign import nan "var nan = NaN;" :: Number
+
+  foreign import infinity "var infinity = Infinity;" :: Number
+
+  foreign import toExponential "function toExponential(n) {\
+                               \  return n.toExponential();\
+                               \}" :: Number -> String
+
+  foreign import toFixed "function toFixed(d) {\
+                         \  return function(n) {\
+                         \    return n.toFixed(d);\
+                         \  };\
+                         \}" :: Number -> Number -> String
+
+  foreign import toPrecision "function toPrecision(d) {\
+                             \  return function(n) {\
+                             \    return n.toPrecision(d);\
+                             \  };\
+                             \}" :: Number -> Number -> String
+
+  foreign import isFinite :: Number -> Boolean
+
+  foreign import parseFloat :: String -> Number
+
+  foreign import parseInt :: String -> Number
+
+  foreign import encodeURIComponent :: String -> String
+
+  foreign import decodeURIComponent :: String -> String
+
+  foreign import encodeURI :: String -> String
+
+  foreign import decodeURI :: String -> String
+
+  foreign import isNaN :: Number -> Boolean
+
+module Math where
+
+  foreign import abs "function abs(n){\
+                     \  return Math.abs(n);\
+                     \}" :: Number -> Number
+
+  foreign import acos "function acos(n){\
+                      \  return Math.acos(n);\
+                      \}" :: Number -> Number
+
+  foreign import asin "function asin(n){\
+                      \  return Math.asin(n);\
+                      \}" :: Number -> Number
+
+  foreign import atan "function atan(n){\
+                      \  return Math.atan(n);\
+                      \}" :: Number -> Number
+
+  foreign import atan2 "function atan2(y){\
+                       \  return function (x) {\
+                       \    return Math.atan2(y, x);\
+                       \  };\
+                       \}" :: Number -> Number -> Number
+
+  foreign import aceil "function aceil(n){\
+                       \  return Math.aceil(n);\
+                       \}" :: Number -> Number
+
+  foreign import cos "function cos(n){\
+                     \  return Math.cos(n);\
+                     \}" :: Number -> Number
+
+  foreign import exp "function exp(n){\
+                     \  return Math.exp(n);\
+                     \}" :: Number -> Number
+
+  foreign import floor "function floor(n){\
+                       \  return Math.floor(n);\
+                       \}" :: Number -> Number
+
+  foreign import log "function log(n){\
+                     \  return Math.log(n);\
+                     \}" :: Number -> Number
+
+  foreign import max "function max(n){\
+                     \  return Math.max(n);\
+                     \}" :: Number -> Number
+
+  foreign import min "function min(n){\
+                     \  return Math.min(n);\
+                     \}" :: Number -> Number
+
+  foreign import pow "function pow(n){\
+                     \  return Math.pow(n);\
+                     \}" :: Number -> Number
+
+  foreign import round "function round(n){\
+                       \  return Math.round(n);\
+                       \}" :: Number -> Number
+
+  foreign import sin "function sin(n){\
+                     \  return Math.sin(n);\
+                     \}" :: Number -> Number
+
+  foreign import sqrt "function sqrt(n){\
+                      \  return Math.sqrt(n);\
+                      \}" :: Number -> Number
+
+  foreign import tan "function tan(n){\
+                     \  return Math.tan(n);\
+                     \}" :: Number -> Number
+
+module Eff where
+
+  foreign import data Eff :: # ! -> * -> *
+
+  foreign import retEff "function retEff(a) { \
+                        \  return function() { \
+                        \    return a; \
+                        \  }; \
+                        \}" :: forall e a. a -> Eff e a
+
+  foreign import bindEff "function bindEff(a) { \
+                         \  return function(f) { \
+                         \    return function() { \
+                         \      return f(a())(); \
+                         \    }; \
+                         \  }; \
+                         \}" :: forall e a b. Eff e a -> (a -> Eff e b) -> Eff e b
+
+  type Pure a = forall e. Eff e a
+
+  foreign import runPure "function runPure(f) { \
+                         \  return f(); \
+                         \}" :: forall a. Pure a -> a
+
+  instance Prelude.Monad (Eff e) where
+    return = retEff
+    (>>=) = bindEff
+
+  foreign import untilE "function untilE(f) {\
+			\  return function() {\
+			\    while (!f()) { }\
+			\    return {};\
+			\  };\
+                        \}" :: forall e. Eff e Boolean -> Eff e {}
+
+  foreign import whileE "function whileE(f) {\
+			\  return function(a) {\
+			\    return function() {\
+			\      while (f()) {\
+                        \        a();\
+                        \      }\
+			\      return {};\
+                        \    };\
+                        \  };\
+                        \}" :: forall e. Eff e Boolean -> Eff e {} -> Eff e {}
+
+  foreign import forE "function forE(lo) {\
+	              \  return function(hi) {\
+	              \    return function(f) {\
+	              \      return function() {\
+	              \        for (var i = lo; i < hi; i++) {\
+		      \          f(i)();\
+                      \        }\
+                      \      };\
+                      \    };\
+                      \  };\
+                      \}" :: forall e. Number -> Number -> (Number -> Eff e {}) -> Eff e {}
+
+
+  foreign import foreachE "function foreachE(as) {\
+	                  \  return function(f) {\
+	                  \    for (var i = 0; i < as.length; i++) {\
+		          \      f(as[i])();\
+                          \    }\
+                          \  };\
+                          \}" :: forall e a. [a] -> (a -> Eff e {}) -> Eff e {}
+
+
+module Random where
+
+  import Eff
+
+  foreign import data Random :: !
+
+  foreign import random "function random() {\
+                        \  return Math.random();\
+                        \}" :: forall e. Eff (random :: Random | e) Number
+
+module Errors where
+
+  import Eff
+
+  foreign import data Error :: * -> !
+
+  foreign import throwError "function throwError(e) { \
+                            \  return function() { \
+                            \    throw e; \
+                            \  }; \
+                            \}" :: forall a e r. e -> Eff (err :: Error e | r) a
+
+  foreign import catchError "function catchError(c) { \
+                            \  return function(t) { \
+                            \    return function() { \
+                            \      try { \
+                            \        return t(); \
+                            \      } catch(e) { \
+                            \        return c(e)(); \
+                            \      }\
+                            \    }; \
+                            \  }; \
+                            \}" :: forall e r a. (e -> Eff r a) -> Eff (err :: Error e | r) a -> Eff r a
+
+module IORef where
+
+  import Eff
+
+  foreign import data Ref :: !
+
+  foreign import data IORef :: * -> *
+
+  foreign import newIORef "function newIORef(val) {\
+                          \  return function () {\
+                          \    return { value: val };\
+                          \  };\
+                          \}" :: forall s r. s -> Eff (ref :: Ref | r) (IORef s)
+
+  foreign import readIORef "function readIORef(ref) {\
+                           \  return function() {\
+                           \    return ref.value;\
+                           \  };\
+                           \}" :: forall s r. IORef s -> Eff (ref :: Ref | r) s
+
+
+  foreign import modifyIORef "function modifyIORef(ref) {\
+                             \  return function(f) {\
+                             \    return function() {\
+                             \      ref.value = f(ref.value);\
+                             \      return {};\
+                             \    };\
+                             \  };\
+                             \}" :: forall s r. IORef s -> (s -> s) -> Eff (ref :: Ref | r) {}
+
+  foreign import writeIORef "function writeIORef(ref) {\
+                            \  return function(val) {\
+                            \    return function() {\
+                            \      ref.value = val;\
+                            \      return {};\
+                            \    };\
+                            \  };\
+                            \}" :: forall s r. IORef s -> s -> Eff (ref :: Ref | r) {}
+
+  foreign import unsafeRunIORef "function unsafeRunIORef(f) {\
+                                \  return f;\
+                                \}" :: forall eff a. Eff (ref :: Ref | eff) a -> Eff eff a
+
+module Trace where
+
+  import Prelude
+  import Eff
+
+  foreign import data Trace :: !
+
+  foreign import trace "function trace(s) { \
+                       \  return function() { \
+                       \    console.log(s); \
+                       \    return {}; \
+                       \  }; \
+                       \}" :: forall r. String -> Eff (trace :: Trace | r) {}
+
+  print :: forall a r. (Prelude.Show a) => a -> Eff (trace :: Trace | r) {}
+  print o = trace (show o)
+
+module ST where
+
+  import Eff
+
+  foreign import data ST :: * -> !
+
+  foreign import data STRef :: * -> * -> *
+
+  foreign import newSTRef "function newSTRef(val) {\
+                          \  return function () {\
+                          \    return { value: val };\
+                          \  };\
+                          \}" :: forall a h r. a -> Eff (st :: ST h | r) (STRef h a)
+
+  foreign import readSTRef "function readSTRef(ref) {\
+                           \  return function() {\
+                           \    return ref.value;\
+                           \  };\
+                           \}" :: forall a h r. STRef h a -> Eff (st :: ST h | r) a
+
+  foreign import modifySTRef "function modifySTRef(ref) {\
+                             \  return function(f) {\
+                             \    return function() {\
+                             \      ref.value = f(ref.value);\
+                             \    };\
+                             \  };\
+                             \}" :: forall a h r. STRef h a -> (a -> a) -> Eff (st :: ST h | r) {}
+
+  foreign import writeSTRef "function writeSTRef(ref) {\
+                            \  return function(a) {\
+                            \    return function() {\
+                            \      ref.value = a;\
+                            \    };\
+                            \  };\
+                            \}" :: forall a h r. STRef h a -> a -> Eff (st :: ST h | r) {}
+
+  foreign import runST "function runST(f) {\
+                       \  return f;\
+                       \}" :: forall a r. (forall h. Eff (st :: ST h | r) a) -> Eff r a
+
diff --git a/psc/Main.hs b/psc/Main.hs
--- a/psc/Main.hs
+++ b/psc/Main.hs
@@ -25,7 +25,7 @@
 import Data.Version (showVersion)
 
 preludeFilename :: IO FilePath
-preludeFilename = Paths.getDataFileName "libraries/prelude/prelude.purs"
+preludeFilename = Paths.getDataFileName "prelude/prelude.purs"
 
 readInput :: Maybe [FilePath] -> IO (Either ParseError [P.Module])
 readInput Nothing = getContents >>= return . P.runIndentParser "" P.parseModules
diff --git a/psci/Main.hs b/psci/Main.hs
--- a/psci/Main.hs
+++ b/psci/Main.hs
@@ -32,7 +32,7 @@
 import qualified Text.Parsec as Parsec (eof)
 
 getPreludeFilename :: IO FilePath
-getPreludeFilename = Paths.getDataFileName "libraries/prelude/prelude.purs"
+getPreludeFilename = Paths.getDataFileName "prelude/prelude.purs"
 
 options :: P.Options
 options = P.Options True False True True True
diff --git a/purescript.cabal b/purescript.cabal
--- a/purescript.cabal
+++ b/purescript.cabal
@@ -1,5 +1,5 @@
 name: purescript
-version: 0.3.10.1
+version: 0.3.11
 cabal-version: >=1.8
 build-type: Simple
 license: MIT
@@ -11,7 +11,7 @@
 description: A small compile-to-JS language with extensible records and type-safe blocks
 category: Language
 author: Phil Freeman <paf31@cantab.net>, Gary Burgess <gary.burgess@gmail.com>
-data-files: libraries/prelude/prelude.purs
+data-files: prelude/prelude.purs
 data-dir: ""
 
 library
diff --git a/src/Language/PureScript/CodeGen/Common.hs b/src/Language/PureScript/CodeGen/Common.hs
--- a/src/Language/PureScript/CodeGen/Common.hs
+++ b/src/Language/PureScript/CodeGen/Common.hs
@@ -21,15 +21,22 @@
 -- |
 -- Convert an Ident into a valid Javascript identifier:
 --
---  * Alphanumeric characters are kept unmodified
+--  * Alphanumeric characters are kept unmodified.
 --
---  * Symbols are encoded as a dollar symbol ($) followed by their ordinal value
+--  * Reserved javascript identifiers are prefixed with '$$'.
 --
+--  * Symbols are prefixed with '$' followed by a symbol name or their ordinal value.
+--
 identToJs :: Ident -> String
+identToJs (Ident name) | nameIsJsReserved name = "$$" ++ name
 identToJs (Ident name) = concatMap identCharToString name
 identToJs (Op op) = concatMap identCharToString op
 identToJs (Escaped name) = name
 
+-- |
+-- Attempts to find a human-readable name for a symbol, if none has been specified returns the
+-- ordinal value.
+--
 identCharToString :: Char -> String
 identCharToString c | isAlphaNum c = [c]
 identCharToString '_' = "_"
@@ -53,4 +60,70 @@
 identCharToString '\\' = "$bslash"
 identCharToString '?' = "$qmark"
 identCharToString '@' = "$at"
+identCharToString '\'' = "$prime"
 identCharToString c = '$' : show (ord c)
+
+-- |
+-- Checks whether an identifier name is reserved in Javascript.
+--
+nameIsJsReserved :: String -> Bool
+nameIsJsReserved name =
+  elem name [ "abstract"
+            , "boolean"
+            , "break"
+            , "byte"
+            , "case"
+            , "catch"
+            , "char"
+            , "class"
+            , "const"
+            , "continue"
+            , "debugger"
+            , "default"
+            , "delete"
+            , "do"
+            , "double"
+            , "else"
+            , "enum"
+            , "export"
+            , "extends"
+            , "final"
+            , "finally"
+            , "float"
+            , "for"
+            , "function"
+            , "goto"
+            , "if"
+            , "implements"
+            , "import"
+            , "in"
+            , "instanceof"
+            , "int"
+            , "interface"
+            , "let"
+            , "long"
+            , "native"
+            , "new"
+            , "package"
+            , "private"
+            , "protected"
+            , "public"
+            , "return"
+            , "short"
+            , "static"
+            , "super"
+            , "switch"
+            , "synchronized"
+            , "this"
+            , "throw"
+            , "throws"
+            , "transient"
+            , "try"
+            , "typeof"
+            , "var"
+            , "void"
+            , "volatile"
+            , "while"
+            , "with"
+            , "yield" ]
+
diff --git a/src/Language/PureScript/CodeGen/JS.hs b/src/Language/PureScript/CodeGen/JS.hs
--- a/src/Language/PureScript/CodeGen/JS.hs
+++ b/src/Language/PureScript/CodeGen/JS.hs
@@ -41,11 +41,12 @@
 import Language.PureScript.CodeGen.JS.AST as AST
 import Language.PureScript.Types
 import Language.PureScript.CodeGen.Optimize
-import Language.PureScript.CodeGen.Common (identToJs)
+import Language.PureScript.CodeGen.Common
 import Language.PureScript.TypeChecker.Monad (canonicalizeDataConstructor)
 
 -- |
--- Generate code in the simplified Javascript intermediate representation for all declarations in a module
+-- Generate code in the simplified Javascript intermediate representation for all declarations in a
+-- module.
 --
 moduleToJs :: Options -> Module -> Environment -> [JS]
 moduleToJs opts (Module pname@(ProperName name) decls) env =
@@ -85,16 +86,36 @@
   Just $ js : setProperty ident (var ident) mp
 declToJs _ _ _ _ = Nothing
 
+-- |
+-- Generate code in the simplified Javascript intermediate representation for setting the property
+-- of an object.
+--
 setProperty :: Ident -> JS -> ModuleName -> [JS]
 setProperty ident@(Op op) val (ModuleName (ProperName moduleName)) =
-  [ JSAssignment (JSAccessor (identToJs ident) (JSVar moduleName)) val
-  , JSAssignment (JSIndexer (JSStringLiteral op) (JSVar moduleName)) (JSAccessor (identToJs ident) (JSVar moduleName)) ]
+  [ JSAssignment (accessor ident (JSVar moduleName)) val
+  , JSAssignment (JSIndexer (JSStringLiteral op) (JSVar moduleName)) (accessor ident (JSVar moduleName)) ]
 setProperty ident val (ModuleName (ProperName moduleName)) =
-  [ JSAssignment (JSAccessor (identToJs ident) (JSVar moduleName)) val ]
+  [ JSAssignment (accessor ident (JSVar moduleName)) val ]
 
+-- |
+-- Generate code in the simplified Javascript intermediate representation for a variable based on a
+-- PureScript identifier.
+--
 var :: Ident -> JS
 var = JSVar . identToJs
 
+-- |
+-- Generate code in the simplified Javascript intermediate representation for an accessor based on
+-- a PureScript identifier. If the name is not valid in Javascript (symbol based, reserved name) an
+-- indexer is returned.
+--
+accessor :: Ident -> JS -> JS
+accessor (Ident name) | nameIsJsReserved name = JSIndexer (JSStringLiteral name)
+accessor ident = JSAccessor (identToJs ident)
+
+-- |
+-- Generate code in the simplified Javascript intermediate representation for a value or expression.
+--
 valueToJs :: Options -> ModuleName -> Environment -> Value -> JS
 valueToJs _ _ _ (NumericLiteral n) = JSNumericLiteral n
 valueToJs _ _ _ (StringLiteral s) = JSStringLiteral s
@@ -104,21 +125,31 @@
 valueToJs opts m e (ObjectUpdate o ps) = JSApp (JSAccessor "extend" (JSVar "Object")) [ valueToJs opts m e o, JSObjectLiteral (map (second (valueToJs opts m e)) ps)]
 valueToJs _ m e (Constructor (Qualified Nothing name)) =
   case M.lookup (m, name) (dataConstructors e) of
-    Just (_, Alias aliasModule aliasIdent) -> qualifiedToJS identToJs (Qualified (Just aliasModule) aliasIdent)
+    Just (_, Alias aliasModule aliasIdent) -> qualifiedToJS id (Qualified (Just aliasModule) aliasIdent)
     _ -> JSVar . runProperName $ name
-valueToJs _ _ _ (Constructor name) = qualifiedToJS runProperName name
+valueToJs _ _ _ (Constructor name) = qualifiedToJS (Ident . runProperName) name
 valueToJs opts m e (Block sts) = JSApp (JSFunction Nothing [] (JSBlock (map (statementToJs opts m e) sts))) []
 valueToJs opts m e (Case values binders) = bindersToJs opts m e binders (map (valueToJs opts m e) values)
 valueToJs opts m e (IfThenElse cond th el) = JSConditional (valueToJs opts m e cond) (valueToJs opts m e th) (valueToJs opts m e el)
 valueToJs opts m e (Accessor prop val) = JSAccessor prop (valueToJs opts m e val)
 valueToJs opts m e (App val arg) = JSApp (valueToJs opts m e val) [valueToJs opts m e arg]
-valueToJs opts m e (Abs arg val) = JSFunction Nothing [identToJs arg] (JSBlock [JSReturn (valueToJs opts m e val)])
+valueToJs opts m e (Abs arg val) = JSFunction Nothing [identToJs arg] (JSBlock [JSReturn (valueToJs opts m (bindName m arg e) val)])
 valueToJs opts m e (TypedValue _ (Abs arg val) ty) | optionsPerformRuntimeTypeChecks opts = let arg' = identToJs arg in JSFunction Nothing [arg'] (JSBlock $ runtimeTypeChecks arg' ty ++ [JSReturn (valueToJs opts m e val)])
 valueToJs _ m e (Var ident) = varToJs m e ident
 valueToJs opts m e (TypedValue _ val _) = valueToJs opts m e val
 valueToJs _ _ _ (TypeClassDictionary _ _) = error "Type class dictionary was not replaced"
 valueToJs _ _ _ _ = error "Invalid argument to valueToJs"
 
+-- |
+-- Temporarily extends the environment to include a local variable name introduced by a lambda
+-- abstraction.
+--
+bindName :: ModuleName -> Ident -> Environment -> Environment
+bindName m ident env = env { names = M.insert (m, ident) (error "Temporary lambda variable type was read", LocalVariable) $ names env }
+
+-- |
+-- Generate code in the simplified Javascript intermediate representation for runtime type checks.
+--
 runtimeTypeChecks :: String -> Type -> [JS]
 runtimeTypeChecks arg ty =
   let
@@ -148,6 +179,10 @@
   arrayCheck :: JS -> JS
   arrayCheck js = JSIfElse (JSUnary Not (JSApp (JSAccessor "isArray" (JSVar "Array")) [js])) (JSBlock [JSThrow (JSStringLiteral "Array expected")]) Nothing
 
+-- |
+-- Generate code in the simplified Javascript intermediate representation for a reference to a
+-- variable.
+--
 varToJs :: ModuleName -> Environment -> Qualified Ident -> JS
 varToJs m e qual@(Qualified _ ident) = go qual
   where
@@ -156,18 +191,25 @@
     Just (_, Alias aliasModule aliasIdent) -> go (Qualified (Just aliasModule) aliasIdent)
     _ -> case qual of
            Qualified Nothing _ -> var ident
-           Qualified (Just (ModuleName (ProperName mn))) (Op op) -> JSIndexer (JSStringLiteral op) (JSVar mn)
-           _ -> qualifiedToJS identToJs qual
+           _ -> qualifiedToJS id qual
   isExtern (Extern ForeignImport) = True
   isExtern (Alias m' ident') = case M.lookup (m', ident') (names e) of
     Just (_, ty') -> isExtern ty'
     Nothing -> error "Undefined alias in varToJs"
   isExtern _ = False
 
-qualifiedToJS :: (a -> String) -> Qualified a -> JS
-qualifiedToJS f (Qualified (Just (ModuleName (ProperName m))) a) = JSAccessor (f a) (JSVar m)
-qualifiedToJS f (Qualified Nothing a) = JSVar (f a)
+-- |
+-- Generate code in the simplified Javascript intermediate representation for a reference to a
+-- variable that may have a qualified name.
+--
+qualifiedToJS :: (a -> Ident) -> Qualified a -> JS
+qualifiedToJS f (Qualified (Just (ModuleName (ProperName m))) a) = accessor (f a) (JSVar m)
+qualifiedToJS f (Qualified Nothing a) = JSVar $ identToJs (f a)
 
+-- |
+-- Generate code in the simplified Javascript intermediate representation for pattern match binders
+-- and guards.
+--
 bindersToJs :: Options -> ModuleName -> Environment -> [([Binder], Maybe Guard, Value)] -> [JS] -> JS
 bindersToJs opts m e binders vals = runGen (map identToJs (unusedNames (binders, vals))) $ do
   valNames <- replicateM (length vals) fresh
@@ -183,6 +225,10 @@
       binderToJs m e v done'' b
     go _ _ _ _ = error "Invalid arguments to bindersToJs"
 
+-- |
+-- Generate code in the simplified Javascript intermediate representation for a pattern match
+-- binder.
+--
 binderToJs :: ModuleName -> Environment -> String -> [JS] -> Binder -> Gen [JS]
 binderToJs _ _ _ done NullBinder = return done
 binderToJs _ _ varName done (StringBinder str) =
@@ -246,6 +292,10 @@
   js <- binderToJs m e varName done binder
   return (JSVariableIntroduction (identToJs ident) (Just (JSVar varName)) : js)
 
+-- |
+-- Checks whether a data constructor is the only constructor for that type, used to simplify the
+-- check when generating code for binders. 
+--
 isOnlyConstructor :: ModuleName -> Environment -> Qualified ProperName -> Bool
 isOnlyConstructor m e ctor =
   let (ty, _) = fromMaybe (error "Data constructor not found") $ qualify m ctor `M.lookup` dataConstructors e
@@ -258,6 +308,10 @@
   typeConstructor (TypeApp ty _) = typeConstructor ty
   typeConstructor fn = error $ "Invalid arguments to typeConstructor: " ++ show fn
 
+-- |
+-- Generate code in the simplified Javascript intermediate representation for a statement in a
+-- PureScript block.
+--
 statementToJs :: Options -> ModuleName -> Environment -> Statement -> JS
 statementToJs opts m e (VariableIntroduction ident value) = JSVariableIntroduction (identToJs ident) (Just (valueToJs opts m e value))
 statementToJs opts m e (Assignment target value) = JSAssignment (JSVar (identToJs target)) (valueToJs opts m e value)
diff --git a/src/Language/PureScript/Parser/Common.hs b/src/Language/PureScript/Parser/Common.hs
--- a/src/Language/PureScript/Parser/Common.hs
+++ b/src/Language/PureScript/Parser/Common.hs
@@ -53,69 +53,6 @@
                   ]
 
 -- |
--- A list of javascript reserved identifiers
---
-reservedJsNames :: [String]
-reservedJsNames = [ "abstract"
-                  , "boolean"
-                  , "break"
-                  , "byte"
-                  , "case"
-                  , "catch"
-                  , "char"
-                  , "class"
-                  , "const"
-                  , "continue"
-                  , "debugger"
-                  , "default"
-                  , "delete"
-                  , "do"
-                  , "double"
-                  , "else"
-                  , "enum"
-                  , "export"
-                  , "extends"
-                  , "final"
-                  , "finally"
-                  , "float"
-                  , "for"
-                  , "function"
-                  , "goto"
-                  , "if"
-                  , "implements"
-                  , "import"
-                  , "in"
-                  , "instanceof"
-                  , "int"
-                  , "interface"
-                  , "let"
-                  , "long"
-                  , "native"
-                  , "new"
-                  , "package"
-                  , "private"
-                  , "protected"
-                  , "public"
-                  , "return"
-                  , "short"
-                  , "static"
-                  , "super"
-                  , "switch"
-                  , "synchronized"
-                  , "this"
-                  , "throw"
-                  , "throws"
-                  , "transient"
-                  , "try"
-                  , "typeof"
-                  , "var"
-                  , "void"
-                  , "volatile"
-                  , "while"
-                  , "with"
-                  , "yield" ]
-
--- |
 -- A list of reserved identifiers for types
 --
 reservedTypeNames :: [String]
@@ -287,12 +224,7 @@
 -- Parse an identifier or parenthesized operator
 --
 parseIdent :: P.Parsec String ParseState Ident
-parseIdent = parseIdent' <|> (Op <$> parens operator)
-  where
-  parseIdent' :: P.Parsec String ParseState Ident
-  parseIdent' = do
-    ident <- identifier
-    return $ if (ident `elem` reservedJsNames) then (Escaped $ "$" ++ ident) else (Ident ident)
+parseIdent = (Ident <$> identifier) <|> (Op <$> parens operator)
 
 -- |
 -- Parse a token inside square brackets
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -34,7 +34,7 @@
 import qualified Data.Map as M
 
 preludeFilename :: IO FilePath
-preludeFilename = Paths.getDataFileName "libraries/prelude/prelude.purs"
+preludeFilename = Paths.getDataFileName "prelude/prelude.purs"
 
 readInput :: [FilePath] -> IO (Either ParseError [P.Module])
 readInput inputFiles = fmap (fmap concat . sequence) $ forM inputFiles $ \inputFile -> do
