packages feed

fay-base (empty) → 0.1.0.0

raw patch · 6 files changed

+1006/−0 lines, 6 filesdep +basedep +faysetup-changed

Dependencies added: base, fay

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2012, Chris Done++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Chris Done nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ fay-base.cabal view
@@ -0,0 +1,24 @@+name:                fay-base+version:             0.1.0.0+synopsis:            The base package for Fay.+description:         The base package for Fay.+                     This package exports Prelude and FFI which you probably want to use with Fay.+license:             BSD3+license-file:        LICENSE+author:              Chris Done+maintainer:          chrisdone@gmail.com+homepage:            https://github.com/faylang/fay-base+bug-reports:         https://github.com/faylang/fay-base/issues+copyright:           2012 Chris Done+category:            Development+build-type:          Simple+cabal-version:       >=1.8+data-files:          src/Prelude.hs src/FFI.hs src/Data/Data.hs++library+  hs-source-dirs:    src+  exposed:           False+  exposed-modules:   Prelude+                    ,FFI+                    ,Data.Data+  build-depends: base == 4.*, fay >= 0.12
+ src/Data/Data.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE PackageImports #-}+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE CPP #-}+module Data.Data+#ifndef FAY+  (Data,Typeable)+#endif+  where++import "base" Data.Data
+ src/FFI.hs view
@@ -0,0 +1,8 @@+{-# LANGUAGE CPP #-}+module FFI+#ifndef FAY+  (module Language.Fay.FFI)+#endif+  where++import Language.Fay.FFI
+ src/Prelude.hs view
@@ -0,0 +1,932 @@+{-# LANGUAGE PackageImports #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-}+{-# OPTIONS -w #-}++module Prelude+#ifndef FAY+  (+  -- Prelude type re-exports+   Base.Char+  ,Base.String+  ,Base.Double+  ,Base.Int+  ,Base.Integer+  ,Base.Bool(..)+  ,Base.Read+  ,Base.Show+  ,Base.Eq+  ,(==)+  ,(/=)+  -- Standard data types+  ,Maybe(..)+  ,maybe+  -- Monads+  ,(>>=)+  ,(>>)+  ,return+  ,when+  ,forM_+  ,mapM_+  ,(=<<)+  ,sequence+  ,sequence_+  -- Num+  ,(*)+  ,(+)+  ,(-)+  -- Ratio+  ,Rational+  -- Ord+  ,Ord+  ,Ordering(..)+  -- An ordering.+  ,(<)+  ,(<=)+  ,(>)+  ,(>=)+  ,compare+  -- Enum+  ,succ+  ,pred+  ,enumFrom+  ,enumFromTo+  ,enumFromBy+  ,enumFromThen+  ,enumFromByTo+  ,enumFromThenTo+  -- Fractional+  ,(/)+  -- Integral+  ,fromIntegral+  ,fromIntegral+  -- Bools+  ,(&&)+  ,(||)+  ,not+  ,otherwise+  -- Show+  ,show+  -- Errors+  ,error+  ,undefined+  ,Either(..)+  ,either+  -- Functions+  ,until+  ,($!)+  ,const+  ,id+  ,(.)+  ,($)+  ,flip+  ,curry+  ,uncurry+  ,snd+  ,fst+  -- Numbers+  ,div+  ,mod+  ,divMod+  ,min+  ,max+  ,recip+  ,negate+  ,abs+  ,signum+  ,pi+  ,exp+  ,sqrt+  ,log+  ,(**)+  ,(^^)+  ,unsafePow+  ,(^)+  ,logBase+  ,sin+  ,tan+  ,cos+  ,asin+  ,atan+  ,acos+  ,sinh+  ,tanh+  ,cosh+  ,asinh+  ,atanh+  ,acosh+  ,properFraction+  ,truncate+  ,round+  ,ceiling+  ,floor+  ,subtract+  ,even+  ,odd+  ,gcd+  ,quot+  ,quot'+  ,quotRem+  ,rem+  ,rem'+  ,lcm+  -- Lists+  ,find+  ,filter+  ,null+  ,map+  ,nub+  ,nub'+  ,elem+  ,notElem+  ,sort+  ,sortBy+  ,insertBy+  ,conc+  ,concat+  ,concatMap+  ,foldr+  ,foldr1+  ,foldl+  ,foldl1+  ,(++)+  ,(!!)+  ,head+  ,tail+  ,init+  ,last+  ,iterate+  ,repeat+  ,replicate+  ,cycle+  ,take+  ,drop+  ,splitAt+  ,takeWhile+  ,dropWhile+  ,span+  ,break+  ,zipWith+  ,zipWith3+  ,zip+  ,zip3+  ,unzip+  ,unzip3+  ,lines+  ,unlines+  ,words+  ,unwords+  ,and+  ,or+  ,any+  ,all+  ,intersperse+  ,prependToAll+  ,intercalate+  ,maximum+  ,minimum+  ,product+  ,sum+  ,scanl+  ,scanl1+  ,scanr+  ,scanr1+  ,lookup+  ,length+  ,length'+  ,reverse+  -- IO+  ,print+  ,putStrLn+  )+#endif+  where++import                  Language.Fay.Types (Fay)+import                  Language.Fay.FFI+import Data.Data+import qualified "base" Prelude as Base+import "base" Prelude (Bool(True,False)+                      ,(||),(&&),seq,Eq,(==),(/=))++--------------------------------------------------------------------------------+-- Aliases of base++type String = Base.String+type Int    = Base.Int+type Double = Base.Double+type Char = Base.Char++--------------------------------------------------------------------------------+-- Standard data types++-- | Maybe type.+data Maybe a = Just a | Nothing+instance Base.Read a => Base.Read (Maybe a)+instance Base.Show a => Base.Show (Maybe a)+instance Typeable a => Typeable (Maybe a)+instance Data a => Data (Maybe a)++-- | Either type.+data Either a b = Left a | Right b++maybe :: t -> (t1 -> t) -> Maybe t1 -> t+maybe m _ Nothing = m+maybe _ f (Just x) = f x++--------------------------------------------------------------------------------+-- Rational++data Rational = Ratio Int Int+instance Base.Show Rational+instance Data Rational+instance Typeable Rational++--------------------------------------------------------------------------------+-- Monads++-- | Monomorphic bind for Fay.+(>>=) :: Fay a -> (a -> Fay b) -> Fay b+(>>=) = ffi "Fay$$bind(%1)(%2)"++-- | Monomorphic then for Fay.+(>>) :: Fay a -> Fay b -> Fay b+(>>) = ffi "Fay$$then(%1)(%2)"++-- | Monomorphic return for Fay.+return :: a -> Fay a+return = ffi "Fay$$return(%1)"++when :: Bool -> Fay a -> Fay ()+when p m = if p then m >> return () else return ()++forM_ :: [t] -> (t -> Fay a) -> Fay ()+forM_ (x:xs) m = m x >> forM_ xs m+forM_ []     _ = return ()++mapM_ :: (a -> Fay b) -> [a] -> Fay ()+mapM_ m (x:xs) = m x >> mapM_ m xs+mapM_ _ []     = return ()++(=<<) :: (a -> Fay b) -> Fay a -> Fay b+f =<< x = x >>= f+infixl 1 =<<++-- | Evaluate each action in the sequence from left to right,+-- and collect the results.+sequence :: [Fay a] -> Fay [a]+sequence ms = foldr k (return []) ms+            where+              k m m' = do { x <- m; xs <- m'; return (x:xs) }++sequence_ :: [Fay a] -> Fay ()+sequence_ []     = return ()+sequence_ (m:ms) = m >> sequence_ ms++--------------------------------------------------------------------------------+-- Num++class Base.Num a => Num a where+  (*) :: a -> a -> a+  (+) :: a -> a -> a+  (-) :: a -> a -> a++instance Num Int+instance Num Double++--------------------------------------------------------------------------------+-- Ord++-- An ordering.+data Ordering = GT | LT | EQ++class (Eq a,Base.Ord a) => Ord a where+  (<)     :: a -> a -> Bool+  (<=)    :: a -> a -> Bool+  (>)     :: a -> a -> Bool+  (>=)    :: a -> a -> Bool++instance Ord Int+instance Ord Double+instance Ord Char++compare :: Ord a => a -> a -> Ordering+compare x y =+  if x > y+     then GT+     else if x < y+             then LT+             else EQ++--------------------------------------------------------------------------------+-- Enum++class (Base.Enum a) => Enum a where++instance Enum Int++succ :: Num a => a -> a+succ x = x + 1++pred :: Num a => a -> a+pred x = x - 1++enumFrom :: Num a => a -> [a]+enumFrom i = i : enumFrom (i + 1)++enumFromTo :: (Ord t, Num t) => t -> t -> [t]+enumFromTo i n =+  if i > n then [] else i : enumFromTo (i + 1) n++enumFromBy :: (Num t) => t -> t -> [t]+enumFromBy fr by = fr : enumFromBy (fr + by) by++enumFromThen :: (Num t) => t -> t -> [t]+enumFromThen fr th = enumFromBy fr (th - fr)++enumFromByTo :: (Ord t, Num t) => t -> t -> t -> [t]+enumFromByTo fr by to = if by < 0 then neg fr else pos fr+  where neg x = if x < to then [] else x : neg (x + by)+        pos x = if x > to then [] else x : pos (x + by)++enumFromThenTo :: (Ord t, Num t) => t -> t -> t -> [t]+enumFromThenTo fr th to = enumFromByTo fr (th - fr) to++--------------------------------------------------------------------------------+-- Fractional++class (Num a,Base.Fractional a) => Fractional a where+  (/) :: a -> a -> a++instance Fractional Double++--------------------------------------------------------------------------------+-- Integral++class (Enum a,Base.Integral a) => Integral a++instance Integral Int++fromIntegral :: Int -> Double+fromIntegral = ffi "%1"++fromInteger :: Int -> Double+fromInteger = ffi "%1"++--------------------------------------------------------------------------------+-- Bools++not :: Bool -> Bool+not p = if p then False else True++otherwise :: Bool+otherwise = True++--------------------------------------------------------------------------------+-- Show++-- | Uses JSON.stringify.+show :: Automatic a -> String+show = ffi "JSON.stringify(%1)"++--------------------------------------------------------------------------------+-- Errors++-- | Throws a JavaScript error.+error :: String -> a+error = ffi "(function() { throw %1 })()"++-- | Throws “undefined” via "error".+undefined :: a+undefined = error "Prelude.undefined"++either :: (a -> c) -> (b -> c) -> Either a b -> c+either f _ (Left a) = f a+either _ g (Right b) = g b++--------------------------------------------------------------------------------+-- Functions++until :: (a -> Bool) -> (a -> a) -> a -> a+until p f x = if p x then x else until p f (f x)++($!) :: (a -> b) -> a -> b+f $! x = x `seq` f x+infixr 0 $!++const :: a -> b -> a+const a _ = a++id :: a -> a+id x = x++(.) :: (t1 -> t) -> (t2 -> t1) -> t2 -> t+(f . g) x = f (g x)+infixr 9 .++($) :: (t1 -> t) -> t1 -> t+f $ x = f x+infixr 0 $++flip :: (t1 -> t2 -> t) -> t2 -> t1 -> t+flip f x y = f y x++curry :: ((a, b) -> c) -> a -> b -> c+curry f x y = f (x, y)++uncurry :: (a -> b -> c) -> (a, b) -> c+uncurry f p = case p of (x, y) -> f x y++snd :: (t, t1) -> t1+snd (_,x) = x++fst :: (t, t1) -> t+fst (x,_) = x++--------------------------------------------------------------------------------+-- Numbers++div :: Int -> Int -> Int+div x y+  | x > 0 && y < 0 = quot (x-1) y - 1+  | x < 0 && y > 0 = quot (x+1) y - 1+div x y            = quot x y+infixl 7 `div`++mod :: Int -> Int -> Int+mod x y+  | x > 0 && y < 0 = rem (x-1) y + y + 1+  | x < 0 && y > 0 = rem (x+1) y + y - 1+mod x y            = rem x y+infixl 7 `mod`++divMod :: Int -> Int -> (Int, Int)+divMod x y+  | x > 0 && y < 0 = case (x-1) `quotRem` y of (q,r) -> (q-1, r+y+1)+  | x < 0 && y > 1 = case (x+1) `quotRem` y of (q,r) -> (q-1, r+y-1)+divMod x y         = quotRem x y++min :: (Num a, Foreign a) => a -> a -> a+min = ffi "Math.min(%1,%2)"++max :: (Num a, Foreign a) => a -> a -> a+max = ffi "Math.max(%1,%2)"++recip :: Double -> Double+recip x = 1 / x++-- | Implemented in Fay.+negate :: Num a => a -> a+negate x = (-x)++-- | Implemented in Fay.+abs :: (Num a, Ord a) => a -> a+abs x = if x < 0 then negate x else x++-- | Implemented in Fay.+signum :: (Num a, Ord a) => a -> a+signum x = if x > 0 then 1 else if x == 0 then 0 else -1++-- | Uses Math.PI.+pi :: Double+pi = ffi "Math.PI"++-- | Uses Math.exp.+exp :: Double -> Double+exp = ffi "Math.exp(%1)"++-- | Uses Math.sqrt.+sqrt :: Double -> Double+sqrt = ffi "Math.sqrt(%1)"++-- | Uses Math.log.+log :: Double -> Double+log = ffi "Math.log(%1)"++-- | Uses Math.pow.+(**) :: Double -> Double -> Double+(**) = unsafePow+infixr 8 **++-- | Uses Math.pow.+(^^) :: Double -> Int -> Double+(^^) = unsafePow+infixr 8 ^^++-- | Uses Math.pow.+unsafePow :: (Num a,Num b) => a -> b -> a+unsafePow = ffi "Math.pow(%1,%2)"++-- | Implemented in Fay, it's not fast.+(^) :: Num a => a -> Int -> a+a ^ b | b < 0  = error "(^): negative exponent"+      | b == 0 = 1+      | even b = let x = a ^ (b `quot` 2) in x * x+a ^ b          = a * a ^ (b - 1)+infixr 8 ^++-- | Implemented in Fay, not fast.+logBase :: Double -> Double -> Double+logBase b x = log x / log b++-- | Uses Math.sin.+sin :: Double -> Double+sin = ffi "Math.sin(%1)"++-- | Uses Math.tan.+tan :: Double -> Double+tan = ffi "Math.tan(%1)"++-- | Uses Math.cos.+cos :: Double -> Double+cos = ffi "Math.cos(%1)"++-- | Uses Math.asin.+asin :: Double -> Double+asin = ffi "Math.asin(%1)"++-- | Uses Math.atan.+atan :: Double -> Double+atan = ffi "Math.atan(%1)"++-- | Uses Math.acos.+acos :: Double -> Double+acos = ffi "Math.acos(%1)"++-- | Implemented in Fay, not fast.+sinh :: Double -> Double+sinh x = (exp x - exp (-x)) / 2++-- | Implemented in Fay, not fast.+tanh :: Double -> Double+tanh x = let a = exp x ; b = exp (-x) in (a - b) / (a + b)++-- | Implemented in Fay, not fast.+cosh :: Double -> Double+cosh x = (exp x + exp (-x)) / 2++-- | Implemented in Fay, not fast.+asinh :: Double -> Double+asinh x = log (x + sqrt(x**2 + 1))++-- | Implemented in Fay, not fast.+atanh :: Double -> Double+atanh x = log ((1 + x) / (1 - x)) / 2++-- | Implemented in Fay, not fast.+acosh :: Double -> Double+acosh x = log (x + sqrt (x**2 - 1))++-- | Implemented in Fay, not fast.+properFraction :: Double -> (Int, Double)+properFraction x = let a = truncate x in (a, x - fromIntegral a)++-- | Implemented in Fay, not fast.+truncate :: Double -> Int+truncate x = if x < 0 then ceiling x else floor x++-- | Uses Math.round.+round :: Double -> Int+round = ffi "Math.round(%1)"++-- | Uses Math.ceil.+ceiling :: Double -> Int+ceiling = ffi "Math.ceil(%1)"++-- | Uses Math.floor.+floor :: Double -> Int+floor = ffi "Math.floor(%1)"++-- | Flip (-).+subtract :: Num a => a -> a -> a+subtract = flip (-)++-- | Implemented in Fay, not fast.+even :: Int -> Bool+even x = x `rem` 2 == 0++-- | not (even x)+odd :: Int -> Bool+odd x = not (even x)++-- | Implemented in Fay, not fast.+gcd :: Int -> Int -> Int+gcd a b = go (abs a) (abs b)+  where go x 0 = x+        go x y = go y (x `rem` y)++-- | Uses quot'.+quot :: Int -> Int -> Int+quot x y = if y == 0 then error "Division by zero" else quot' x y+infixl 7 `quot`++-- | Uses ~~(a/b).+quot' :: Int -> Int -> Int+quot' = ffi "~~(%1/%2)"++-- | (quot x y, rem x y)+quotRem :: Int -> Int -> (Int, Int)+quotRem x y = (quot x y, rem x y)++-- | Uses rem'.+rem :: Int -> Int -> Int+rem x y = if y == 0 then error "Division by zero" else rem' x y+infixl 7 `rem`++-- | Uses %%.+rem' :: Int -> Int -> Int+rem' = ffi "%1 %% %2"++lcm :: Int -> Int -> Int+lcm _ 0 = 0+lcm 0 _ = 0+lcm a b = abs ((a `quot` (gcd a b)) * b)++--------------------------------------------------------------------------------+-- Lists++find :: (a -> Bool) -> [a] -> Maybe a+find p (x:xs) = if p x then Just x else find p xs+find _ [] = Nothing++filter :: (a -> Bool) -> [a] -> [a]+filter p (x:xs) = if p x then x : filter p xs else filter p xs+filter _ []     = []++null :: [t] -> Bool+null [] = True+null _ = False++map :: (a -> b) -> [a] -> [b]+map _ []     = []+map f (x:xs) = f x : map f xs++nub :: Eq a => [a] -> [a]+nub ls = nub' ls []++nub' :: Eq a => [a] -> [a] -> [a]+nub' []     _ = []+nub' (x:xs) ls =+  if elem x ls+     then nub' xs ls+     else x : nub' xs (x : ls)++elem :: Eq a => a -> [a] -> Bool+elem x (y:ys)   = x == y || elem x ys+elem _ []       = False++notElem :: Eq a => a -> [a] -> Bool+notElem x ys = not (elem x ys)++sort :: Ord a => [a] -> [a]+sort = sortBy compare++sortBy :: (t -> t -> Ordering) -> [t] -> [t]+sortBy cmp = foldr (insertBy cmp) []++insertBy :: (a -> a -> Ordering) -> a -> [a] -> [a]+insertBy _   x [] = [x]+insertBy cmp x ys =+  case ys of+    [] -> [x]+    y:ys' ->+      case cmp x y of+         GT -> y : insertBy cmp x ys'+         _  -> x : ys++-- | Append two lists.+conc :: [a] -> [a] -> [a]+conc (x:xs) ys = x : conc xs ys+conc []     ys = ys++concat :: [[a]] -> [a]+concat = foldr conc []++concatMap :: (a -> [b]) -> [a] -> [b]+concatMap f = foldr ((++) . f) []++foldr :: (t -> t1 -> t1) -> t1 -> [t] -> t1+foldr _ z []     = z+foldr f z (x:xs) = f x (foldr f z xs)++foldr1 :: (a -> a -> a) -> [a] -> a+foldr1 _ [x]    = x+foldr1 f (x:xs) = f x (foldr1 f xs)+foldr1 _ []     = error "foldr1: empty list"++foldl :: (t1 -> t -> t1) -> t1 -> [t] -> t1+foldl _ z []     = z+foldl f z (x:xs) = foldl f (f z x) xs++foldl1 :: (a -> a -> a) -> [a] -> a+foldl1 f (x:xs) = foldl f x xs+foldl1 _ []     = error "foldl1: empty list"++(++) :: [a] -> [a] -> [a]+x ++ y = conc x y+infixr 5 ++++(!!) :: [a] -> Int -> a+a !! b = if b < 0 then error "(!!): negative index" else go a b+  where go []    _ = error "(!!): index too large"+        go (h:_) 0 = h+        go (_:t) n = go t (n-1)+infixl 9 !!++head :: [a] -> a+head []    = error "head: empty list"+head (h:_) = h++tail :: [a] -> [a]+tail []    = error "tail: empty list"+tail (_:t) = t++init :: [a] -> [a]+init []    = error "init: empty list"+init [a]   = [a]+init (h:t) = h : init t++last :: [a] -> a+last []    = error "last: empty list"+last [a]   = a+last (_:t) = last t++iterate :: (a -> a) -> a -> [a]+iterate f x = x : iterate f (f x)++repeat :: a -> [a]+repeat x = x : repeat x++replicate :: Int -> a -> [a]+replicate 0 _ = []+replicate n x = if n < 0 then error "replicate: negative length"+                         else x : replicate (n-1) x++cycle :: [a] -> [a]+cycle [] = error "cycle: empty list"+cycle xs = xs' where xs' = xs ++ xs'++take :: Int -> [a] -> [a]+take 0 _  = []+take _ [] = []+take n (x:xs) = if n < 0 then error "take: negative length"+                         else x : take (n-1) xs++drop :: Int -> [a] -> [a]+drop 0 xs = xs+drop _ [] = []+drop n (_:xs) = if n < 0 then error "drop: negative length"+                         else drop (n-1) xs++splitAt :: Int -> [a] -> ([a], [a])+splitAt 0 xs     = ([], xs)+splitAt _ []     = ([], [])+splitAt n (x:xs) = if n < 0 then error "splitAt: negative length"+                            else case splitAt (n-1) xs of (a,b) -> (x:a, b)++takeWhile :: (a -> Bool) -> [a] -> [a]+takeWhile _ []     = []+takeWhile p (x:xs) = if p x then x : takeWhile p xs else []++dropWhile :: (a -> Bool) -> [a] -> [a]+dropWhile _ []     = []+dropWhile p (x:xs) = if p x then dropWhile p xs else x:xs++span :: (a -> Bool) -> [a] -> ([a], [a])+span _ []     = ([], [])+span p (x:xs) = if p x then case span p xs of (a,b) -> (x:a, b) else ([], x:xs)++break :: (a -> Bool) -> [a] -> ([a], [a])+break p = span (not . p)++zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]+zipWith f (a:as) (b:bs) = f a b : zipWith f as bs+zipWith _ _      _      = []++zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]+zipWith3 f (a:as) (b:bs) (c:cs) = f a b c : zipWith3 f as bs cs+zipWith3 _ _      _      _      = []++zip :: [a] -> [b] -> [(a,b)]+zip (a:as) (b:bs) = (a,b) : zip as bs+zip _      _      = []++zip3 :: [a] -> [b] -> [c] -> [(a, b, c)]+zip3 (a:as) (b:bs) (c:cs) = (a,b,c) : zip3 as bs cs+zip3 _      _      _      = []++unzip :: [(a, b)] -> ([a], [b])+unzip ((x,y):ps) = case unzip ps of (xs,ys) -> (x:xs, y:ys)+unzip []         = ([], [])++unzip3 :: [(a, b, c)] -> ([a], [b], [c])+unzip3 ((x,y,z):ps) = case unzip3 ps of (xs,ys,zs) -> (x:xs, y:ys, z:zs)+unzip3 []           = ([], [], [])++lines :: String -> [String]+lines []   = []+lines s    = case break isLineBreak s of (a, [])   -> [a]+                                         (a, _:cs) -> a : lines cs+  where isLineBreak c = c == '\r' || c == '\n'++unlines :: [String] -> String+unlines = intercalate "\n"++words :: String -> [String]+words str = words' (dropWhile isSpace str)+  where words' []  = []+        words' s = case break isSpace s of (a,b) -> a : words b+        isSpace c  = c `elem` " \t\r\n\f\v"++unwords :: [String] -> String+unwords = intercalate " "++and :: [Bool] -> Bool+and []     = True+and (x:xs) = x && and xs++or :: [Bool] -> Bool+or []     = False+or (x:xs) = x || or xs++any :: (a -> Bool) -> [a] -> Bool+any _ []     = False+any p (x:xs) = p x || any p xs++all :: (a -> Bool) -> [a] -> Bool+all _ []     = True+all p (x:xs) = p x && all p xs++intersperse :: a -> [a] -> [a]+intersperse _   []      = []+intersperse sep (x:xs)  = x : prependToAll sep xs++prependToAll :: a -> [a] -> [a]+prependToAll _   []     = []+prependToAll sep (x:xs) = sep : x : prependToAll sep xs++intercalate :: [a] -> [[a]] -> [a]+intercalate xs xss = concat (intersperse xs xss)++maximum :: (Num a, Foreign a) => [a] -> a+maximum [] = error "maximum: empty list"+maximum xs = foldl1 max xs++minimum :: (Num a, Foreign a) => [a] -> a+minimum [] = error "minimum: empty list"+minimum xs = foldl1 min xs++product :: Num a => [a] -> a+product [] = error "product: empty list"+product xs = foldl (*) 1 xs++sum :: Num a => [a] -> a+sum [] = error "sum: empty list"+sum xs = foldl (+) 0 xs++scanl :: (a -> b -> a) -> a -> [b] -> [a]+scanl f z l = z : case l of [] -> []+                            (x:xs) -> scanl f (f z x) xs++scanl1 :: (a -> a -> a) -> [a] -> [a]+scanl1 _ [] = []+scanl1 f (x:xs) = scanl f x xs++scanr :: (a -> b -> b) -> b -> [a] -> [b]+scanr _ z [] = [z]+scanr f z (x:xs) = case scanr f z xs of (h:t) -> f x h : h : t+                                        _     -> undefined++scanr1 :: (a -> a -> a) -> [a] -> [a]+scanr1 _ []     = []+scanr1 _ [x]    = [x]+scanr1 f (x:xs) = case scanr1 f xs of (h:t) -> f x h : h : t+                                      _     -> undefined++lookup :: Eq a1 => a1 -> [(a1, a)] -> Maybe a+lookup _key []          =  Nothing+lookup  key ((x,y):xys) =+  if key == x+     then Just y+     else lookup key xys++length :: [a] -> Int+length xs = length' 0 xs++length' :: Int -> [a] -> Int+length' acc (_:xs) = length' (acc+1) xs+length' acc _ = acc++reverse :: [a] -> [a]+reverse (x:xs) = reverse xs ++ [x]+reverse [] = []++--------------------------------------------------------------------------------+-- IO++print :: Automatic a -> Fay ()+print = ffi "(function(x) { if (console && console.log) console.log(x) })(%1)"++putStrLn :: String -> Fay ()+putStrLn = ffi "(function(x) { if (console && console.log) console.log(x) })(%1)"