From 93399267c4adb1aa1858f156917080d21d6d7cc3 Mon Sep 17 00:00:00 2001 From: Harry Garrood Date: Thu, 30 Apr 2015 19:31:30 +0100 Subject: [PATCH 1/8] Remove (:), cons --- src/Prelude.purs | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/Prelude.purs b/src/Prelude.purs index ea2dd8da..29fcbc37 100644 --- a/src/Prelude.purs +++ b/src/Prelude.purs @@ -5,7 +5,6 @@ module Prelude , const , asTypeOf , otherwise - , (:), cons , Semigroupoid, compose, (<<<), (>>>) , Category, id , Functor, map, (<$>), (<#>), void @@ -116,30 +115,6 @@ asTypeOf x _ = x otherwise :: Boolean otherwise = true --- | Attaches an element to the front of an array, creating a new array. --- | --- | ```purescript --- | cons 1 [2, 3, 4] = [1, 2, 3, 4] --- | ``` --- | --- | Note, the running time of this function is `O(n)`. -foreign import cons - """ - function cons(e) { - return function(l) { - return [e].concat(l); - }; - } - """ :: forall a. a -> [a] -> [a] - -infixr 6 : - --- | An infix alias for `cons`. --- | --- | Note, the running time of this function is `O(n)`. -(:) :: forall a. a -> [a] -> [a] -(:) = cons - infixr 9 >>> infixr 9 <<< From fa7e430d1b5340aed931af0986bb1ec7b3e8e99a Mon Sep 17 00:00:00 2001 From: Harry Garrood Date: Thu, 30 Apr 2015 19:32:57 +0100 Subject: [PATCH 2/8] Remove Array sugar --- src/Prelude.purs | 28 ++++++++++++++-------------- src/Prelude/Unsafe.purs | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Prelude.purs b/src/Prelude.purs index 29fcbc37..ef47ae97 100644 --- a/src/Prelude.purs +++ b/src/Prelude.purs @@ -174,7 +174,7 @@ class Functor f where instance functorFn :: Functor ((->) r) where map = compose -instance functorArray :: Functor [] where +instance functorArray :: Functor Array where map = arrayMap foreign import arrayMap @@ -189,7 +189,7 @@ foreign import arrayMap return result; }; } - """ :: forall a b. (a -> b) -> [a] -> [b] + """ :: forall a b. (a -> b) -> Array a -> Array b (<$>) :: forall f a b. (Functor f) => (a -> b) -> f a -> f b (<$>) = map @@ -247,7 +247,7 @@ class (Functor f) <= Apply f where instance applyFn :: Apply ((->) r) where apply f g x = f x (g x) -instance applyArray :: Apply [] where +instance applyArray :: Apply Array where apply = ap (<*>) :: forall f a b. (Apply f) => f (a -> b) -> f a -> f b @@ -277,7 +277,7 @@ class (Apply f) <= Applicative f where instance applicativeFn :: Applicative ((->) r) where pure = const -instance applicativeArray :: Applicative [] where +instance applicativeArray :: Applicative Array where pure x = [x] -- | `return` is an alias for `pure`. @@ -333,7 +333,7 @@ class (Apply m) <= Bind m where instance bindFn :: Bind ((->) r) where bind m f x = f (m x) x -instance bindArray :: Bind [] where +instance bindArray :: Bind Array where bind = arrayBind foreign import arrayBind @@ -347,7 +347,7 @@ foreign import arrayBind return result; }; } - """ :: forall a b. [a] -> (a -> [b]) -> [b] + """ :: forall a b. Array a -> (a -> Array b) -> Array b (>>=) :: forall m a b. (Monad m) => m a -> (a -> m b) -> m b (>>=) = bind @@ -366,7 +366,7 @@ class (Applicative m, Bind m) <= Monad m instance monadFn :: Monad ((->) r) -instance monadArray :: Monad [] +instance monadArray :: Monad Array -- | `liftM1` provides a default implementation of `(<$>)` for any -- | [`Monad`](#monad), without using `(<$>)` as provided by the @@ -437,7 +437,7 @@ instance semigroupOrdering :: Semigroup Ordering where append GT _ = GT append EQ y = y -instance semigroupArray :: Semigroup [a] where +instance semigroupArray :: Semigroup (Array a) where append = concatArray foreign import concatString @@ -456,7 +456,7 @@ foreign import concatArray return xs.concat(ys); }; } - """ :: forall a. [a] -> [a] -> [a] + """ :: forall a. Array a -> Array a -> Array a infixl 6 + infixl 7 * @@ -708,7 +708,7 @@ instance eqString :: Eq String where instance eqUnit :: Eq Unit where eq _ _ = true -instance eqArray :: (Eq a) => Eq [a] where +instance eqArray :: (Eq a) => Eq (Array a) where eq = eqArrayImpl (==) instance eqOrdering :: Eq Ordering where @@ -748,7 +748,7 @@ foreign import eqArrayImpl }; }; } - """ :: forall a. (a -> a -> Boolean) -> [a] -> [a] -> Boolean + """ :: forall a. (a -> a -> Boolean) -> Array a -> Array a -> Boolean -- | The `Ordering` data type represents the three possible outcomes of -- | comparing two values: @@ -786,7 +786,7 @@ instance ordChar :: Ord Char where instance ordUnit :: Ord Unit where compare _ _ = EQ -instance ordArray :: (Ord a) => Ord [a] where +instance ordArray :: (Ord a) => Ord (Array a) where compare [] [] = EQ compare [] _ = LT compare _ [] = GT @@ -1028,7 +1028,7 @@ instance showString :: Show String where instance showUnit :: Show Unit where show _ = "unit" -instance showArray :: (Show a) => Show [a] where +instance showArray :: (Show a) => Show (Array a) where show = showArrayImpl show instance showOrdering :: Show Ordering where @@ -1075,4 +1075,4 @@ foreign import showArrayImpl return '[' + ss.join(',') + ']'; }; } - """ :: forall a. (a -> String) -> [a] -> String + """ :: forall a. (a -> String) -> Array a -> String diff --git a/src/Prelude/Unsafe.purs b/src/Prelude/Unsafe.purs index 490365f9..024296bc 100644 --- a/src/Prelude/Unsafe.purs +++ b/src/Prelude/Unsafe.purs @@ -10,4 +10,4 @@ foreign import unsafeIndex return xs[n]; }; } - """ :: forall a. [a] -> Number -> a + """ :: forall a. Array a -> Number -> a From 5b90e700682f948dd3a908d36b3feead7bf010bc Mon Sep 17 00:00:00 2001 From: Harry Garrood Date: Thu, 30 Apr 2015 19:33:15 +0100 Subject: [PATCH 3/8] Implement ordArray without cons binders --- src/Prelude.purs | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/src/Prelude.purs b/src/Prelude.purs index ef47ae97..c507d6b2 100644 --- a/src/Prelude.purs +++ b/src/Prelude.purs @@ -787,12 +787,42 @@ instance ordUnit :: Ord Unit where compare _ _ = EQ instance ordArray :: (Ord a) => Ord (Array a) where - compare [] [] = EQ - compare [] _ = LT - compare _ [] = GT - compare (x:xs) (y:ys) = case compare x y of - EQ -> compare xs ys - other -> other + compare = compareArrayImpl checkEqOr EQ + where + checkEqOr a b callback = + case compare a b of + EQ -> unit + other -> callback other + +foreign import compareArrayImpl + """ + function compareArrayImpl(checkEqOr) { + return function(eq) { + return function(xs) { + return function(ys) { + var minlen = xs.length + var maxlen = ys.length + var result = null + + if (maxlen < minlen) { + var tmp = minlen + minlen = maxlen + maxlen = tmp + } + + for (var i = 0; i < minlen && result === null; ++i) { + checkEqOr(xs[i])(ys[i])(function(other) { result = other }) + } + + if (result === null) { + result = eq + } + return result + } + } + } + } + """ :: forall a. (a -> a -> (Ordering -> Unit) -> Unit) -> Ordering -> Array a -> Array a -> Ordering instance ordOrdering :: Ord Ordering where compare LT LT = EQ From d368a7f19684df2bdf863d3e1c51b552929566d6 Mon Sep 17 00:00:00 2001 From: Harry Garrood Date: Thu, 30 Apr 2015 19:42:51 +0100 Subject: [PATCH 4/8] Docs updates --- docs/Prelude.Unsafe.md | 2 +- docs/Prelude.md | 42 +++++++++--------------------------------- 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/docs/Prelude.Unsafe.md b/docs/Prelude.Unsafe.md index d48e43dc..c53cdc97 100644 --- a/docs/Prelude.Unsafe.md +++ b/docs/Prelude.Unsafe.md @@ -5,7 +5,7 @@ #### `unsafeIndex` ``` purescript -unsafeIndex :: forall a. [a] -> Number -> a +unsafeIndex :: forall a. Array a -> Number -> a ``` Find the element of an array at the specified index. diff --git a/docs/Prelude.md b/docs/Prelude.md index 086d1603..0d24cee3 100644 --- a/docs/Prelude.md +++ b/docs/Prelude.md @@ -119,30 +119,6 @@ max x y | x >= y = x | otherwise = y ``` -#### `cons` - -``` purescript -cons :: forall a. a -> [a] -> [a] -``` - -Attaches an element to the front of an array, creating a new array. - -```purescript -cons 1 [2, 3, 4] = [1, 2, 3, 4] -``` - -Note, the running time of this function is `O(n)`. - -#### `(:)` - -``` purescript -(:) :: forall a. a -> [a] -> [a] -``` - -An infix alias for `cons`. - -Note, the running time of this function is `O(n)`. - #### `Semigroupoid` ``` purescript @@ -234,7 +210,7 @@ instance functorFn :: Functor (Prim.Function r) #### `functorArray` ``` purescript -instance functorArray :: Functor Prim.Array +instance functorArray :: Functor Array ``` @@ -316,7 +292,7 @@ instance applyFn :: Apply (Prim.Function r) #### `applyArray` ``` purescript -instance applyArray :: Apply Prim.Array +instance applyArray :: Apply Array ``` @@ -363,7 +339,7 @@ instance applicativeFn :: Applicative (Prim.Function r) #### `applicativeArray` ``` purescript -instance applicativeArray :: Applicative Prim.Array +instance applicativeArray :: Applicative Array ``` @@ -438,7 +414,7 @@ instance bindFn :: Bind (Prim.Function r) #### `bindArray` ``` purescript -instance bindArray :: Bind Prim.Array +instance bindArray :: Bind Array ``` @@ -476,7 +452,7 @@ instance monadFn :: Monad (Prim.Function r) #### `monadArray` ``` purescript -instance monadArray :: Monad Prim.Array +instance monadArray :: Monad Array ``` @@ -579,7 +555,7 @@ instance semigroupOrdering :: Semigroup Ordering #### `semigroupArray` ``` purescript -instance semigroupArray :: Semigroup [a] +instance semigroupArray :: Semigroup (Array a) ``` @@ -871,7 +847,7 @@ instance eqUnit :: Eq Unit #### `eqArray` ``` purescript -instance eqArray :: (Eq a) => Eq [a] +instance eqArray :: (Eq a) => Eq (Array a) ``` @@ -958,7 +934,7 @@ instance ordUnit :: Ord Unit #### `ordArray` ``` purescript -instance ordArray :: (Ord a) => Ord [a] +instance ordArray :: (Ord a) => Ord (Array a) ``` @@ -1273,7 +1249,7 @@ instance showUnit :: Show Unit #### `showArray` ``` purescript -instance showArray :: (Show a) => Show [a] +instance showArray :: (Show a) => Show (Array a) ``` From c0d07898a7da6d632d44b1054124160404093cc2 Mon Sep 17 00:00:00 2001 From: Harry Garrood Date: Thu, 30 Apr 2015 20:13:10 +0100 Subject: [PATCH 5/8] Very basic test suite --- test/Main.purs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 test/Main.purs diff --git a/test/Main.purs b/test/Main.purs new file mode 100644 index 00000000..1ecbf1a6 --- /dev/null +++ b/test/Main.purs @@ -0,0 +1,29 @@ + +module Main where + +import Console (log) +import Control.Monad.Eff + +foreign import throwError + """ + function throwError(msg) { + throw new Error(msg) + } + """ :: forall e. String -> Eff e Unit + +check :: forall e a. (Show a, Ord a) => Ordering -> a -> a -> Eff e Unit +check expected a b = + let actual = compare a b + in if actual == expected + then return unit + else throwError (show a <> " `compare` " <> show b <> ": " <> + "expected " <> show expected <> ", got " <> show actual) + +main = do + check EQ [] ([] :: Array Number) + check LT [] [0] + check EQ [1,2,3] [1,2,3] + check LT [1,1,3] [1,2,3] + + + log "All good!" From 63b366619578a3d80c3594c7a6bbab67ce5e897e Mon Sep 17 00:00:00 2001 From: Harry Garrood Date: Thu, 30 Apr 2015 20:21:03 +0100 Subject: [PATCH 6/8] Fix ordArrayImpl --- src/Prelude.purs | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/src/Prelude.purs b/src/Prelude.purs index c507d6b2..22a171af 100644 --- a/src/Prelude.purs +++ b/src/Prelude.purs @@ -787,12 +787,38 @@ instance ordUnit :: Ord Unit where compare _ _ = EQ instance ordArray :: (Ord a) => Ord (Array a) where - compare = compareArrayImpl checkEqOr EQ - where - checkEqOr a b callback = - case compare a b of - EQ -> unit - other -> callback other + compare xs ys = compare 0 $ ordArrayImpl (\x y -> case compare x y of + EQ -> 0 + LT -> 1 + GT -> -1) xs ys + +foreign import ordArrayImpl """ + function ordArrayImpl(f) { + return function (xs) { + return function (ys) { + var i = 0; + var xlen = xs.length; + var ylen = ys.length; + while (i < xlen && i < ylen) { + var x = xs[i]; + var y = ys[i]; + var o = f(x)(y); + if (o !== 0) { + return o; + } + i++; + } + if (xlen == ylen) { + return 0; + } else if (xlen > ylen) { + return -1; + } else { + return 1; + } + }; + }; + } + """ :: forall a. (a -> a -> Int) -> Array a -> Array a -> Int foreign import compareArrayImpl """ From 1b04eb2ce50ed09a1105c6a43a8c89d0182d27b6 Mon Sep 17 00:00:00 2001 From: Harry Garrood Date: Thu, 30 Apr 2015 20:22:24 +0100 Subject: [PATCH 7/8] More tests --- test/Main.purs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/Main.purs b/test/Main.purs index 1ecbf1a6..1b21bc58 100644 --- a/test/Main.purs +++ b/test/Main.purs @@ -22,8 +22,9 @@ check expected a b = main = do check EQ [] ([] :: Array Number) check LT [] [0] + check GT [0] [] check EQ [1,2,3] [1,2,3] check LT [1,1,3] [1,2,3] - + check GT [1,3,3] [1,2,3] log "All good!" From 3440a621514252bd27f9ca6fecd3e87bfb587f5c Mon Sep 17 00:00:00 2001 From: Harry Garrood Date: Thu, 30 Apr 2015 20:23:51 +0100 Subject: [PATCH 8/8] Remove unused function compareArrayImpl --- src/Prelude.purs | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/Prelude.purs b/src/Prelude.purs index 22a171af..8b73f4ad 100644 --- a/src/Prelude.purs +++ b/src/Prelude.purs @@ -820,36 +820,6 @@ foreign import ordArrayImpl """ } """ :: forall a. (a -> a -> Int) -> Array a -> Array a -> Int -foreign import compareArrayImpl - """ - function compareArrayImpl(checkEqOr) { - return function(eq) { - return function(xs) { - return function(ys) { - var minlen = xs.length - var maxlen = ys.length - var result = null - - if (maxlen < minlen) { - var tmp = minlen - minlen = maxlen - maxlen = tmp - } - - for (var i = 0; i < minlen && result === null; ++i) { - checkEqOr(xs[i])(ys[i])(function(other) { result = other }) - } - - if (result === null) { - result = eq - } - return result - } - } - } - } - """ :: forall a. (a -> a -> (Ordering -> Unit) -> Unit) -> Ordering -> Array a -> Array a -> Ordering - instance ordOrdering :: Ord Ordering where compare LT LT = EQ compare EQ EQ = EQ