-
Notifications
You must be signed in to change notification settings - Fork 1
Attempting some stack safety strategies #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: nub-ord-bench
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,6 +73,11 @@ module Data.List | |
, groupAllBy | ||
, partition | ||
|
||
, nubByAdjacentReverse | ||
, addIndexReverse | ||
, mapReverse | ||
, nubBySafe | ||
|
||
, nub | ||
, nubBy | ||
, nubEq | ||
|
@@ -698,6 +703,23 @@ nubBy p = | |
-- Add indices so we can recover original order after deduplicating. | ||
<<< addIndexReverse | ||
|
||
-- Same as nubBy, but eliminates nubByAdjacentReverse. | ||
-- This is just for exploring stack safety. | ||
-- It doesn't actually remove duplicates. | ||
nubBySafe :: forall a. (a -> a -> Ordering) -> List a -> List a | ||
nubBySafe p = | ||
-- Discard indices, just keep original values. | ||
mapReverse snd | ||
-- Sort by index to recover original order. | ||
-- Use `flip` to sort in reverse order in anticipation of final `mapReverse`. | ||
<<< sortBy (flip compare `on` fst) | ||
-- Removing neighboring duplicates. | ||
-- <<< nubByAdjacentReverse (\a b -> (p `on` snd) a b == EQ) | ||
-- Sort by original values to cluster duplicates. | ||
<<< sortBy (p `on` snd) | ||
-- Add indices so we can recover original order after deduplicating. | ||
<<< addIndexReverse | ||
|
||
-- | Remove duplicate elements from a list. | ||
-- | Keeps the first occurrence of each element in the input list, | ||
-- | in the same order they appear in the input list. | ||
|
@@ -860,7 +882,10 @@ foldM f b (a : as) = f b a >>= \b' -> foldM f b' as | |
-- | | ||
-- | Running time: `O(n)` | ||
mapReverse :: forall a b. (a -> b) -> List a -> List b | ||
mapReverse f = go Nil | ||
mapReverse f l = reverse $ map f l | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using this slower, but definitely stack safe alternative (not saying the other version is stack unsafe, but just trying to eliminate unknowns). |
||
|
||
mapReverse2 :: forall a b. (a -> b) -> List a -> List b | ||
mapReverse2 f = go Nil | ||
where | ||
go :: List b -> List a -> List b | ||
go acc Nil = acc | ||
|
@@ -876,7 +901,10 @@ mapReverse f = go Nil | |
-- | | ||
-- | Running time: `O(n)` | ||
addIndexReverse :: forall a. List a -> List (Tuple Int a) | ||
addIndexReverse = go 0 Nil | ||
addIndexReverse = reverse <<< mapWithIndex Tuple | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be stack safe too, right? |
||
|
||
addIndexReverse2 :: forall a. List a -> List (Tuple Int a) | ||
addIndexReverse2 = go 0 Nil | ||
where | ||
go :: Int -> List (Tuple Int a) -> List a -> List (Tuple Int a) | ||
go i acc Nil = acc | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem