purescript 0.3.10.1 → 0.3.11
raw patch · 9 files changed
+1212/−1153 lines, 9 files
Files
- libraries/prelude/prelude.purs +0/−1064
- prelude/prelude.purs +1064/−0
- psc/Main.hs +1/−1
- psci/Main.hs +1/−1
- purescript.cabal +2/−2
- src/Language/PureScript/CodeGen/Common.hs +75/−2
- src/Language/PureScript/CodeGen/JS.hs +67/−13
- src/Language/PureScript/Parser/Common.hs +1/−69
- tests/Main.hs +1/−1
− libraries/prelude/prelude.purs
@@ -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-
+ prelude/prelude.purs view
@@ -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+
psc/Main.hs view
@@ -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
psci/Main.hs view
@@ -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
purescript.cabal view
@@ -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
src/Language/PureScript/CodeGen/Common.hs view
@@ -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" ]+
src/Language/PureScript/CodeGen/JS.hs view
@@ -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)
src/Language/PureScript/Parser/Common.hs view
@@ -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
tests/Main.hs view
@@ -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