diff --git a/src/Data/Array.purs b/src/Data/Array.purs index 9e5b2cb2..11c68d17 100644 --- a/src/Data/Array.purs +++ b/src/Data/Array.purs @@ -7,8 +7,10 @@ -- | for many use cases due to their poor asymptotics. module Data.Array ( (!!) + , index , (..) , cons + , uncons , (:) , snoc , singleton @@ -17,7 +19,6 @@ module Data.Array , tail , init , null - , map , mapMaybe , catMaybes , length @@ -25,7 +26,6 @@ module Data.Array , findLastIndex , elemIndex , elemLastIndex - , append , concat , reverse , span @@ -54,25 +54,42 @@ module Data.Array , group' , groupBy , replicate + , foldlArray + , foldrArray ) where import Control.Alt (Alt) import Control.Alternative (Alternative) import Control.MonadPlus (MonadPlus) import Control.Plus (Plus) -import Data.Function (Fn4(), runFn4) -import Data.Int (Int(), toNumber) +import Data.Function +import Data.Int (toNumber) import Data.Maybe (Maybe(..), maybe, isJust) import Data.Monoid (Monoid) -import Prelude.Unsafe (unsafeIndex) -infixl 8 !! - --- | This operator provides a safe way to read a value at a particular index +foreign import indexImpl + "function indexImpl(just, nothing, xs, i) {\ + \ if (i < 0 || i >= xs.length) {\ + \ return nothing;\ + \ } else {\ + \ return just(xs[i]);\ + \ }\ + \}" :: forall a. Fn4 (forall r. r -> Maybe r) + (forall r. Maybe r) + (Array a) + Int + (Maybe a) + +-- | This function provides a safe way to read a value at a particular index -- | from an array. -(!!) :: forall a. [a] -> Int -> Maybe a -(!!) xs n | n < zero || n >= length xs = Nothing - | otherwise = Just (xs `unsafeIndex` toNumber n) +index :: forall a. Array a -> Int -> Maybe a +index = runFn4 indexImpl Just Nothing + +infixl 8 !! + +-- | An infix version of `index`. +(!!) :: forall a. Array a -> Int -> Maybe a +(!!) = index -- | Attaches an element to the front of an array, creating a new array. -- | @@ -88,14 +105,14 @@ foreign import cons return [e].concat(l); }; } - """ :: forall a. a -> [a] -> [a] + """ :: forall a. a -> Array a -> Array a infixr 6 : -- | An infix alias for `cons`. -- | -- | Note, the running time of this function is `O(n)`. -(:) :: forall a. a -> [a] -> [a] +(:) :: forall a. a -> Array a -> Array a (:) = cons -- | Append an element to the end of an array, creating a new array. @@ -108,40 +125,55 @@ foreign import snoc return l1; }; } - """ :: forall a. [a] -> a -> [a] + """ :: forall a. Array a -> a -> Array a + +foreign import unconsImpl + "function unconsImpl(just, nothing, xs) {\ + \ if (xs.length === 0) {\ + \ return nothing;\ + \ } else {\ + \ return just({ head: xs[0], tail: xs.slice(1) });\ + \ }\ + \}":: forall a. Fn3 (forall r. r -> Maybe r) + (forall r. Maybe r) + (Array a) + (Maybe { head :: a, tail :: Array a }) + +-- | Break an array into its first element, and the remaining elements +uncons :: forall a. Array a -> Maybe { head :: a, tail :: Array a } +uncons = runFn3 unconsImpl Just Nothing -- | Create an array of one element -singleton :: forall a. a -> [a] +singleton :: forall a. a -> Array a singleton a = [a] -- | Get the first element in an array, or `Nothing` if the array is empty -- | -- | Running time: `O(1)`. -head :: forall a. [a] -> Maybe a -head xs = xs !! zero +head :: forall a. Array a -> Maybe a +head xs = _.head <$> uncons xs -- | Get the last element in an array, or `Nothing` if the array is empty -- | -- | Running time: `O(1)`. -last :: forall a. [a] -> Maybe a +last :: forall a. Array a -> Maybe a last xs = xs !! (length xs - one) -- | Get all but the first element of an array, creating a new array, or `Nothing` if the array is empty -- | -- | Running time: `O(n)` where `n` is the length of the array -tail :: forall a. [a] -> Maybe [a] -tail (_ : xs) = Just xs -tail _ = Nothing +tail :: forall a. Array a -> Maybe (Array a) +tail xs = _.tail <$> uncons xs -- | Get all but the last element of an array, creating a new array, or `Nothing` if the array is empty. -- | -- | Running time: `O(n)` where `n` is the length of the array -init :: forall a. [a] -> Maybe [a] +init :: forall a. Array a -> Maybe (Array a) init [] = Nothing init xs = Just (slice zero (length xs - one) xs) -- | Test whether an array is empty. -null :: forall a. [a] -> Boolean +null :: forall a. Array a -> Boolean null [] = true null _ = false @@ -151,10 +183,10 @@ foreign import length function length (xs) { return xs.length; } - """ :: forall a. [a] -> Int + """ :: forall a. Array a -> Int -- | Find the first index for which a predicate holds. -findIndex :: forall a. (a -> Boolean) -> [a] -> Maybe Int +findIndex :: forall a. (a -> Boolean) -> Array a -> Maybe Int findIndex f xs = runFn4 findIndexJS Just Nothing f xs foreign import findIndexJS @@ -165,10 +197,10 @@ foreign import findIndexJS } return nothing; }; - """ :: forall a. Fn4 (Int -> Maybe Int) (Maybe Int) (a -> Boolean) [a] (Maybe Int) + """ :: forall a. Fn4 (Int -> Maybe Int) (Maybe Int) (a -> Boolean) (Array a) (Maybe Int) -- | Find the last index for which a predicate holds. -findLastIndex :: forall a. (a -> Boolean) -> [a] -> Maybe Int +findLastIndex :: forall a. (a -> Boolean) -> Array a -> Maybe Int findLastIndex f xs = runFn4 findLastIndexJS Just Nothing f xs foreign import findLastIndexJS @@ -179,26 +211,16 @@ foreign import findLastIndexJS } return nothing; } - """ :: forall a. Fn4 (Int -> Maybe Int) (Maybe Int) (a -> Boolean) [a] (Maybe Int) + """ :: forall a. Fn4 (Int -> Maybe Int) (Maybe Int) (a -> Boolean) (Array a) (Maybe Int) -- | Find the index of the first element equal to the specified element. -elemIndex :: forall a. (Eq a) => a -> [a] -> Maybe Int +elemIndex :: forall a. (Eq a) => a -> Array a -> Maybe Int elemIndex x = findIndex ((==) x) -- | Find the index of the last element equal to the specified element. -elemLastIndex :: forall a. (Eq a) => a -> [a] -> Maybe Int +elemLastIndex :: forall a. (Eq a) => a -> Array a -> Maybe Int elemLastIndex x = findLastIndex ((==) x) --- | Concatenate two arrays, creating a new array. -foreign import append - """ - function append (l1) { - return function (l2) { - return l1.concat(l2); - }; - } - """ :: forall a. [a] -> [a] -> [a] - -- | Flatten an array of arrays, creating a new array. foreign import concat """ @@ -209,7 +231,7 @@ foreign import concat } return result; } - """ :: forall a. [[a]] -> [a] + """ :: forall a. Array (Array a) -> Array a -- | Reverse an array, creating a copy foreign import reverse @@ -217,7 +239,7 @@ foreign import reverse function reverse (l) { return l.slice().reverse(); } - """ :: forall a. [a] -> [a] + """ :: forall a. Array a -> Array a -- | Split an array into two parts: -- | @@ -229,12 +251,13 @@ foreign import reverse -- | ```purescript -- | span (\n -> n % 2 == 1) [1,3,2,4,5] == { init: [1,3], rest: [2,4,5] } -- | ``` -span :: forall a. (a -> Boolean) -> [a] -> { init :: [a], rest :: [a] } -span = go [] +span :: forall a. (a -> Boolean) -> Array a -> { init :: Array a, rest :: Array a } +span p = go [] where - go :: forall a. [a] -> (a -> Boolean) -> [a] -> { init :: [a], rest :: [a] } - go acc p (x:xs) | p x = go (x:acc) p xs - go acc _ xs = { init: reverse acc, rest: xs } + go :: Array a -> Array a -> { init :: Array a, rest :: Array a } + go acc xs = case uncons xs of + Just { head: x, tail: xs } | p x -> go (x : acc) xs + _ -> { init: reverse acc, rest: xs } -- | Drop a number of elements from the start of an array, creating a new array. foreign import drop @@ -244,21 +267,21 @@ foreign import drop return n < 1 ? l : l.slice(n); }; } - """ :: forall a. Int -> [a] -> [a] + """ :: forall a. Int -> Array a -> Array a -- | Remove the longest initial subarray for which all element satisfy the specified predicate, -- | creating a new array. -dropWhile :: forall a. (a -> Boolean) -> [a] -> [a] +dropWhile :: forall a. (a -> Boolean) -> Array a -> Array a dropWhile p xs = (span p xs).rest -- | Keep only a number of elements from the start of an array, creating a new array. -take :: forall a. Int -> [a] -> [a] +take :: forall a. Int -> Array a -> Array a take n xs | n < one = [] | otherwise = slice zero n xs -- | Calculate the longest initial subarray for which all element satisfy the specified predicate, -- | creating a new array. -takeWhile :: forall a. (a -> Boolean) -> [a] -> [a] +takeWhile :: forall a. (a -> Boolean) -> Array a -> Array a takeWhile p xs = (span p xs).init -- | Create a copy of a subarray @@ -271,7 +294,7 @@ foreign import slice }; }; } - """ :: forall a. Int -> Int -> [a] -> [a] + """ :: forall a. Int -> Int -> Array a -> Array a -- | Insert an element at the specified index, creating a new array. foreign import insertAt @@ -285,7 +308,7 @@ foreign import insertAt }; }; } - """ :: forall a. Int -> a -> [a] -> [a] + """ :: forall a. Int -> a -> Array a -> Array a -- | Delete the element at the specified index, creating a new array. foreign import deleteAt @@ -299,7 +322,7 @@ foreign import deleteAt }; }; } - """ :: forall a. Int -> Int -> [a] -> [a] + """ :: forall a. Int -> Int -> Array a -> Array a -- | Change the element at the specified index, creating a new array. foreign import updateAt @@ -314,84 +337,60 @@ foreign import updateAt }; }; } - """ :: forall a. Int -> a -> [a] -> [a] + """ :: forall a. Int -> a -> Array a -> Array a -- | Apply a function to the element at the specified index, creating a new array. -modifyAt :: forall a. Int -> (a -> a) -> [a] -> [a] +modifyAt :: forall a. Int -> (a -> a) -> Array a -> Array a modifyAt i f xs = maybe xs (\x -> updateAt i (f x) xs) (xs !! i) -- | Delete the first element of an array which is equal to the specified value, -- | creating a new array. -delete :: forall a. (Eq a) => a -> [a] -> [a] -delete = deleteBy (==) +delete :: forall a. (Eq a) => a -> Array a -> Array a +delete = deleteBy eq -- | Delete the first element of an array which matches the specified value, under the -- | equivalence relation provided in the first argument, creating a new array. -deleteBy :: forall a. (a -> a -> Boolean) -> a -> [a] -> [a] -deleteBy _ _ [] = [] +deleteBy :: forall a. (a -> a -> Boolean) -> a -> Array a -> Array a +deleteBy _ _ [] = [] deleteBy eq x ys = maybe ys (\i -> deleteAt i one ys) (findIndex (eq x) ys) infix 5 \\ -- | Delete the first occurrence of each element in the second array from the first array, -- | creating a new array. -(\\) :: forall a. (Eq a) => [a] -> [a] -> [a] +(\\) :: forall a. (Eq a) => Array a -> Array a -> Array a (\\) xs ys = go xs ys where go xs [] = xs go [] _ = [] - go xs (y:ys) = go (delete y xs) ys + go xs ys = case uncons ys of + Just o -> go (delete o.head xs) o.tail -- | Calculate the intersection of two arrays, creating a new array. -intersect :: forall a. (Eq a) => [a] -> [a] -> [a] -intersect = intersectBy (==) +intersect :: forall a. (Eq a) => Array a -> Array a -> Array a +intersect = intersectBy eq -- | Calculate the intersection of two arrays, using the specified equivalence relation -- | to compare elements, creating a new array. -intersectBy :: forall a. (a -> a -> Boolean) -> [a] -> [a] -> [a] +intersectBy :: forall a. (a -> a -> Boolean) -> Array a -> Array a -> Array a intersectBy _ [] _ = [] intersectBy _ _ [] = [] intersectBy eq xs ys = filter (\x -> isJust (findIndex (eq x) ys)) xs -- | Apply a function to each element in an array, and flatten the results -- | into a single, new array. -foreign import concatMap - """ - function concatMap (f) { - return function (arr) { - var result = []; - for (var i = 0, l = arr.length; i < l; i++) { - Array.prototype.push.apply(result, f(arr[i])); - } - return result; - }; - } - """ :: forall a b. (a -> [b]) -> [a] -> [b] - --- | Apply a function to each element in an array, creating a new array. -foreign import map - """ - function map (f) { - return function (arr) { - var l = arr.length; - var result = new Array(l); - for (var i = 0; i < l; i++) { - result[i] = f(arr[i]); - } - return result; - }; - } - """ :: forall a b. (a -> b) -> [a] -> [b] +concatMap :: forall a b. (a -> Array b) -> Array a -> Array b +concatMap f xs = xs >>= f -- | Apply a function to each element in an array, keeping only the results which -- | contain a value, creating a new array. -mapMaybe :: forall a b. (a -> Maybe b) -> [a] -> [b] +mapMaybe :: forall a b. (a -> Maybe b) -> Array a -> Array b mapMaybe f = concatMap (maybe [] singleton <<< f) -- | Filter an array of optional values, keeping only the elements which contain -- | a value, creating a new array. -catMaybes :: forall a. [Maybe a] -> [a] -catMaybes = concatMap (maybe [] singleton) +catMaybes :: forall a. Array (Maybe a) -> Array a +catMaybes = mapMaybe id -- | Filter an array, keeping the elements which satisfy a predicate function, -- | creating a new array. @@ -407,7 +406,7 @@ foreign import filter return result; }; } - """ :: forall a. (a -> Boolean) -> [a] -> [a] + """ :: forall a. (a -> Boolean) -> Array a -> Array a -- | Create an array containing a range of integers, including both endpoints. foreign import range @@ -424,12 +423,12 @@ foreign import range return result; }; } - """ :: Int -> Int -> [Int] + """ :: Int -> Int -> Array Int infix 8 .. -- | An infix synonym for `range`. -(..) :: Int -> Int -> [Int] +(..) :: Int -> Int -> Array Int (..) = range -- | Apply a function to pairs of elements at the same index in two arrays, @@ -456,25 +455,26 @@ foreign import zipWith }; }; } - """ :: forall a b c. (a -> b -> c) -> [a] -> [b] -> [c] + """ :: forall a b c. (a -> b -> c) -> Array a -> Array b -> Array c -- | Remove the duplicates from an array, creating a new array. -nub :: forall a. (Eq a) => [a] -> [a] -nub = nubBy (==) +nub :: forall a. (Eq a) => Array a -> Array a +nub = nubBy eq -- | Remove the duplicates from an array, where element equality is determined by the -- | specified equivalence relation, creating a new array. -nubBy :: forall a. (a -> a -> Boolean) -> [a] -> [a] +nubBy :: forall a. (a -> a -> Boolean) -> Array a -> Array a nubBy _ [] = [] -nubBy (==) (x:xs) = x : nubBy (==) (filter (\y -> not (x == y)) xs) +nubBy eq xs = case uncons xs of + Just o -> o.head : nubBy eq (filter (\y -> not (o.head `eq` y)) o.tail) -- | Sort the elements of an array in increasing order, creating a new array. -sort :: forall a. (Ord a) => [a] -> [a] +sort :: forall a. (Ord a) => Array a -> Array a sort xs = sortBy compare xs -- | Sort the elements of an array in increasing order, where elements are compared using -- | the specified partial ordering, creating a new array. -sortBy :: forall a. (a -> a -> Ordering) -> [a] -> [a] +sortBy :: forall a. (a -> a -> Ordering) -> Array a -> Array a sortBy comp xs = sortJS comp' xs where comp' x y = case comp x y of @@ -491,7 +491,7 @@ foreign import sortJS }); }; } - """ :: forall a. (a -> a -> Number) -> [a] -> [a] + """ :: forall a. (a -> a -> Int) -> Array a -> Array a -- | Group equal, consecutive elements of an array into arrays. -- | @@ -500,8 +500,8 @@ foreign import sortJS -- | ```purescript -- | group [1,1,2,2,1] == [[1,1],[2,2],[1]] -- | ``` -group :: forall a. (Eq a) => [a] -> [[a]] -group xs = groupBy (==) xs +group :: forall a. (Eq a) => Array a -> Array (Array a) +group xs = groupBy eq xs -- | Sort and group the elements of an array into arrays. -- | @@ -510,18 +510,19 @@ group xs = groupBy (==) xs -- | ```purescript -- | group [1,1,2,2,1] == [[1,1,1],[2,2]] -- | ``` -group' :: forall a. (Ord a) => [a] -> [[a]] +group' :: forall a. (Ord a) => Array a -> Array (Array a) group' = group <<< sort -- | Group equal, consecutive elements of an array into arrays, using the specified -- | equivalence relation to detemine equality. -groupBy :: forall a. (a -> a -> Boolean) -> [a] -> [[a]] -groupBy = go [] +groupBy :: forall a. (a -> a -> Boolean) -> Array a -> Array (Array a) +groupBy op = go [] where - go :: forall a. [[a]] -> (a -> a -> Boolean) -> [a] -> [[a]] - go acc _ [] = reverse acc - go acc op (x:xs) = let sp = span (op x) xs - in go ((x:sp.init):acc) op sp.rest + go :: Array (Array a) -> Array a -> Array (Array a) + go acc [] = reverse acc + go acc xs = case uncons xs of + Just o -> let sp = span (op o.head) o.tail + in go ((o.head : sp.init) : acc) sp.rest -- | Create an array with repeated instances of a value. foreign import replicate @@ -534,34 +535,46 @@ foreign import replicate return r; }; } - """ :: forall a. Int -> a -> [a] - -instance functorArray :: Functor [] where - (<$>) = map + """ :: forall a. Int -> a -> Array a -instance applyArray :: Apply [] where - (<*>) = ap - -instance applicativeArray :: Applicative [] where - pure = singleton - -instance bindArray :: Bind [] where - (>>=) = flip concatMap - -instance monadArray :: Monad [] - -instance semigroupArray :: Semigroup [a] where - (<>) = append +-- | Fold an array from the right +foreign import foldrArray + """ + function foldrArray(f) { + return function(z) { + return function(xs) { + var acc = z; + for (var i = xs.length - 1; i >= 0; --i) { + acc = f(xs[i])(acc); + } + return acc; + }; + }; + } + """ :: forall a b. (a -> b -> b) -> b -> Array a -> b -instance monoidArray :: Monoid [a] where - mempty = [] +-- | Fold an array from the left +foreign import foldlArray + """ + function foldlArray(f) { + return function(z) { + return function(xs) { + var acc = z; + for (var i = 0, len = xs.length; i < len; ++i) { + acc = f(acc)(xs[i]); + } + return acc; + }; + }; + } + """ :: forall a b. (b -> a -> b) -> b -> Array a -> b -instance altArray :: Alt [] where - (<|>) = append +instance altArray :: Alt Array where + alt = append -instance plusArray :: Plus [] where +instance plusArray :: Plus Array where empty = [] -instance alternativeArray :: Alternative [] +instance alternativeArray :: Alternative Array -instance monadPlusArray :: MonadPlus [] +instance monadPlusArray :: MonadPlus Array diff --git a/src/Data/Array/ST.purs b/src/Data/Array/ST.purs index 92e6eed6..13925524 100644 --- a/src/Data/Array/ST.purs +++ b/src/Data/Array/ST.purs @@ -19,7 +19,6 @@ module Data.Array.ST import Control.Monad.Eff (Eff()) import Control.Monad.ST (ST()) import Data.Function (Fn2(), runFn2, Fn3(), runFn3, Fn4(), runFn4) -import Data.Int (Int()) import Data.Maybe (Maybe(..)) -- | A reference to a mutable array. @@ -41,7 +40,7 @@ type Assoc a = { value :: a, index :: Int } foreign import runSTArray """ function runSTArray(f) { return f; - }""" :: forall a r. (forall h. Eff (st :: ST h | r) (STArray h a)) -> Eff r [a] + }""" :: forall a r. (forall h. Eff (st :: ST h | r) (STArray h a)) -> Eff r (Array a) -- | Create an empty mutable array. foreign import emptySTArray """ @@ -89,11 +88,11 @@ foreign import pushAllSTArrayImpl """ return arr.push.apply(arr, as); }; }""" :: forall a h r. Fn2 (STArray h a) - [a] + (Array a) (Eff (st :: ST h | r) Int) -- | Append the values in an immutable array to the end of a mutable array. -pushAllSTArray :: forall a h r. STArray h a -> [a] -> Eff (st :: ST h | r) Int +pushAllSTArray :: forall a h r. STArray h a -> Array a -> Eff (st :: ST h | r) Int pushAllSTArray = runFn2 pushAllSTArrayImpl -- | Append an element to the end of a mutable array. @@ -108,11 +107,11 @@ foreign import spliceSTArrayImpl """ }""" :: forall a h r. Fn4 (STArray h a) Int Int - [a] - (Eff (st :: ST h | r) [a]) + (Array a) + (Eff (st :: ST h | r) (Array a)) -- | Remove and/or insert elements from/into a mutable array at the specified index. -spliceSTArray :: forall a h r. STArray h a -> Int -> Int -> [a] -> Eff (st :: ST h | r) [a] +spliceSTArray :: forall a h r. STArray h a -> Int -> Int -> Array a -> Eff (st :: ST h | r) (Array a) spliceSTArray = runFn4 spliceSTArrayImpl foreign import copyImpl """ @@ -123,11 +122,11 @@ foreign import copyImpl """ }""" :: forall a b h r. a -> Eff (st :: ST h | r) b -- | Create an immutable copy of a mutable array. -freeze :: forall a h r. STArray h a -> Eff (st :: ST h | r) [a] +freeze :: forall a h r. STArray h a -> Eff (st :: ST h | r) (Array a) freeze = copyImpl -- | Create a mutable copy of an immutable array. -thaw :: forall a h r. [a] -> Eff (st :: ST h | r) (STArray h a) +thaw :: forall a h r. Array a -> Eff (st :: ST h | r) (STArray h a) thaw = copyImpl -- | Create an immutable copy of a mutable array, where each element @@ -141,4 +140,4 @@ foreign import toAssocArray """ as[i] = {value: arr[i], index: i}; return as; }; - }""" :: forall a h r. STArray h a -> Eff (st :: ST h | r) [Assoc a] + }""" :: forall a h r. STArray h a -> Eff (st :: ST h | r) (Array (Assoc a)) diff --git a/src/Data/Array/Unsafe.purs b/src/Data/Array/Unsafe.purs index 3b2300e6..3a17a3c5 100644 --- a/src/Data/Array/Unsafe.purs +++ b/src/Data/Array/Unsafe.purs @@ -5,31 +5,42 @@ module Data.Array.Unsafe where -import Data.Int (Int(), toNumber) +import Data.Int (toNumber) import Data.Maybe.Unsafe (fromJust) -import Prelude.Unsafe (unsafeIndex) import qualified Data.Array as A +-- | Find the element of an array at the specified index. +-- | +-- | Note: this function can cause unpredictable failure at runtime if the index is out-of-bounds. +foreign import unsafeIndex + """ + function unsafeIndex(xs) { + return function(n) { + return xs[n]; + }; + } + """ :: forall a. Array a -> Int -> a + -- | Get the first element of a non-empty array. -- | -- | Running time: `O(1)`. -head :: forall a. [a] -> a +head :: forall a. Array a -> a head xs = unsafeIndex xs 0 -- | Get all but the first element of a non-empty array. -- | -- | Running time: `O(n)`, where `n` is the length of the array. -tail :: forall a. [a] -> [a] -tail (_ : xs) = xs +tail :: forall a. Array a -> Array a +tail xs = (fromJust (A.uncons xs)).tail -- | Get the last element of a non-empty array. -- | -- | Running time: `O(1)`. -last :: forall a. [a] -> a -last xs = unsafeIndex xs (toNumber (A.length xs - one)) +last :: forall a. Array a -> a +last xs = unsafeIndex xs (A.length xs - one) -- | Get all but the last element of a non-empty array. -- | -- | Running time: `O(n)`, where `n` is the length of the array. -init :: forall a. [a] -> [a] +init :: forall a. Array a -> Array a init = fromJust <<< A.init diff --git a/test/Test/Data/Array.purs b/test/Test/Data/Array.purs index c56cc1c6..4aff059a 100644 --- a/test/Test/Data/Array.purs +++ b/test/Test/Data/Array.purs @@ -2,7 +2,6 @@ module Test.Data.Array (testArray) where import Console (log) import Data.Array -import Data.Int (Int(), fromNumber, toNumber) import Data.Maybe (Maybe(..)) import Test.Common @@ -17,13 +16,13 @@ testArray = do assert $ [1, 2, 3] /= [1, 2, 2] log "(!!) should return Just x when the index is within the bounds of the array" - assert $ [1, 2, 3] !! (fromNumber 0) == (Just 1) - assert $ [1, 2, 3] !! (fromNumber 1) == (Just 2) - assert $ [1, 2, 3] !! (fromNumber 2) == (Just 3) + assert $ [1, 2, 3] !! 0 == (Just 1) + assert $ [1, 2, 3] !! 1 == (Just 2) + assert $ [1, 2, 3] !! 2 == (Just 3) log "(!!) should return Nothing when the index is outside of the bounds of the array" - assert $ [1, 2, 3] !! (fromNumber 6) == Nothing - assert $ [1, 2, 3] !! (fromNumber (-1)) == Nothing + assert $ [1, 2, 3] !! 6 == Nothing + assert $ [1, 2, 3] !! (-1) == Nothing log "snoc should add an item to the end of an array" assert $ [1, 2, 3] `snoc` 4 == [1, 2, 3, 4] @@ -66,24 +65,24 @@ testArray = do assert $ null nil == true log "length should return the number of items in an array" - assert $ length nil == fromNumber 0 - assert $ length [1] == fromNumber 1 - assert $ length [1, 2, 3, 4, 5] == fromNumber 5 + assert $ length nil == 0 + assert $ length [1] == 1 + assert $ length [1, 2, 3, 4, 5] == 5 log "findIndex should return the index of an item that a predicate returns true for in an array" - assert $ (findIndex (/= 1) [1, 2, 1]) == Just (fromNumber 1) + assert $ (findIndex (/= 1) [1, 2, 1]) == Just 1 assert $ (findIndex (== 3) [1, 2, 1]) == Nothing log "findLastIndex should return the last index of an item in an array" - assert $ (findLastIndex (/= 1) [2, 1, 2]) == Just (fromNumber 2) + assert $ (findLastIndex (/= 1) [2, 1, 2]) == Just 2 assert $ (findLastIndex (== 3) [2, 1, 2]) == Nothing log "elemIndex should return the index of an item that a predicate returns true for in an array" - assert $ (elemIndex 1 [1, 2, 1]) == Just (fromNumber 0) + assert $ (elemIndex 1 [1, 2, 1]) == Just 0 assert $ (elemIndex 4 [1, 2, 1]) == Nothing log "elemLastIndex should return the last index of an item in an array" - assert $ (elemLastIndex 1 [1, 2, 1]) == Just (fromNumber 2) + assert $ (elemLastIndex 1 [1, 2, 1]) == Just 2 assert $ (elemLastIndex 4 [1, 2, 1]) == Nothing log "append should joint two arrays" @@ -106,9 +105,9 @@ testArray = do assert $ spanResult.rest == [4, 5, 6, 7] log "drop should remove the specified number of items from the front of an array" - assert $ (drop (fromNumber 1) [1, 2, 3]) == [2, 3] - assert $ (drop (fromNumber 2) [1, 2, 3]) == [3] - assert $ (drop (fromNumber 1) nil) == nil + assert $ (drop 1 [1, 2, 3]) == [2, 3] + assert $ (drop 2 [1, 2, 3]) == [3] + assert $ (drop 1 nil) == nil log "dropWhile should remove all values that match a predicate from the front of an array" assert $ (dropWhile (/= 1) [1, 2, 3]) == [1, 2, 3] @@ -116,9 +115,9 @@ testArray = do assert $ (dropWhile (/= 1) nil) == nil log "take should keep the specified number of items from the front of an array, discarding the rest" - assert $ (take (fromNumber 1) [1, 2, 3]) == [1] - assert $ (take (fromNumber 2) [1, 2, 3]) == [1, 2] - assert $ (take (fromNumber 1) nil) == nil + assert $ (take 1 [1, 2, 3]) == [1] + assert $ (take 2 [1, 2, 3]) == [1, 2] + assert $ (take 1 nil) == nil log "takeWhile should keep all values that match a predicate from the front of an array" assert $ (takeWhile (/= 2) [1, 2, 3]) == [1] @@ -126,22 +125,22 @@ testArray = do assert $ (takeWhile (/= 1) nil) == nil log "insertAt should add an item at the specified index" - assert $ (insertAt (fromNumber 0) 1 [2, 3]) == [1, 2, 3] - assert $ (insertAt (fromNumber 1) 1 [2, 3]) == [2, 1, 3] + assert $ (insertAt 0 1 [2, 3]) == [1, 2, 3] + assert $ (insertAt 1 1 [2, 3]) == [2, 1, 3] log "deleteAt should remove an item at the specified index" - assert $ (deleteAt (fromNumber 0) (fromNumber 1) [1, 2, 3]) == [2, 3] - assert $ (deleteAt (fromNumber 1) (fromNumber 1) [1, 2, 3]) == [1, 3] + assert $ (deleteAt 0 1 [1, 2, 3]) == [2, 3] + assert $ (deleteAt 1 1 [1, 2, 3]) == [1, 3] log "updateAt should replace an item at the specified index" - assert $ (updateAt (fromNumber 0) 9 [1, 2, 3]) == [9, 2, 3] - assert $ (updateAt (fromNumber 1) 9 [1, 2, 3]) == [1, 9, 3] - assert $ (updateAt (fromNumber 1) 9 nil) == nil + assert $ (updateAt 0 9 [1, 2, 3]) == [9, 2, 3] + assert $ (updateAt 1 9 [1, 2, 3]) == [1, 9, 3] + assert $ (updateAt 1 9 nil) == nil log "modifyAt should update an item at the specified index" - assert $ (modifyAt (fromNumber 0) (+ 1) [1, 2, 3]) == [2, 2, 3] - assert $ (modifyAt (fromNumber 1) (+ 1) [1, 2, 3]) == [1, 3, 3] - assert $ (modifyAt (fromNumber 1) (+ 1) nil) == nil + assert $ (modifyAt 0 (+ 1) [1, 2, 3]) == [2, 2, 3] + assert $ (modifyAt 1 (+ 1) [1, 2, 3]) == [1, 3, 3] + assert $ (modifyAt 1 (+ 1) nil) == nil log "delete should remove the first matching item from an array" assert $ delete 1 [1, 2, 1] == [2, 1] @@ -173,11 +172,11 @@ testArray = do assert $ catMaybes [Nothing, Just 2, Nothing, Just 4] == [2, 4] log "filter should remove items that don't match a predicate" - assert $ filter odd (map toNumber $ range zero (fromNumber 10)) == [1, 3, 5, 7, 9] + assert $ filter odd (range 0 10) == [1, 3, 5, 7, 9] log "range should create an inclusive array of integers for the specified start and end" - assert $ (map toNumber $ range zero (fromNumber 5)) == [0, 1, 2, 3, 4, 5] - assert $ (map toNumber $ range (fromNumber 2) (fromNumber (-3))) == [2, 1, 0, -1, -2, -3] + assert $ (range 0 5) == [0, 1, 2, 3, 4, 5] + assert $ (range 2 (-3)) == [2, 1, 0, -1, -2, -3] log "zipWith should use the specified function to zip two lists together" assert $ zipWith (\x y -> [show x, y]) [1, 2, 3] ["a", "b", "c"] == [["1", "a"], ["2", "b"], ["3", "c"]] @@ -205,16 +204,16 @@ testArray = do assert $ groupBy (\x y -> odd x && odd y) [1, 1, 2, 2, 3, 3] == [[1, 1], [2], [2], [3, 3]] log "replicate should produce an array containg an item a specified number of times" - assert $ replicate (fromNumber 3) true == [true, true, true] - assert $ replicate (fromNumber 1) "foo" == ["foo"] - assert $ replicate (fromNumber 0) "foo" == [] - assert $ replicate (fromNumber (-1)) "foo" == [] + assert $ replicate 3 true == [true, true, true] + assert $ replicate 1 "foo" == ["foo"] + assert $ replicate 0 "foo" == [] + assert $ replicate (-1) "foo" == [] -nil :: [Number] +nil :: Array Int nil = [] -odd :: Number -> Boolean -odd n = (fromNumber n) `mod` (fromNumber 2) /= zero +odd :: Int -> Boolean +odd n = n `mod` 2 /= zero -doubleAndOrig :: Number -> [Number] +doubleAndOrig :: Int -> Array Int doubleAndOrig x = [x * 2, x]