-
Notifications
You must be signed in to change notification settings - Fork 186
Added HasCallStack to partial functions #493
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: master
Are you sure you want to change the base?
Changes from 3 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 |
|---|---|---|
|
|
@@ -411,6 +411,9 @@ import qualified Control.Category as Category | |
| import Data.Coerce | ||
| #endif | ||
|
|
||
| #if __GLASGOW_HASKELL__ >= 800 | ||
| import GHC.Stack (HasCallStack) | ||
| #endif | ||
|
|
||
| {-------------------------------------------------------------------- | ||
| Operators | ||
|
|
@@ -423,7 +426,11 @@ infixl 9 !,!?,\\ -- | |
| -- > fromList [(5,'a'), (3,'b')] ! 1 Error: element not in the map | ||
| -- > fromList [(5,'a'), (3,'b')] ! 5 == 'a' | ||
|
|
||
| #if __GLASGOW_HASKELL__ >= 800 | ||
| (!) :: (HasCallStack, Ord k) => Map k a -> k -> a | ||
| #else | ||
| (!) :: Ord k => Map k a -> k -> a | ||
| #endif | ||
| (!) m k = find k m | ||
| #if __GLASGOW_HASKELL__ | ||
| {-# INLINE (!) #-} | ||
|
|
@@ -1433,7 +1440,11 @@ alterFYoneda = go | |
| -- > findIndex 6 (fromList [(5,"a"), (3,"b")]) Error: element is not in the map | ||
|
|
||
| -- See Note: Type of local 'go' function | ||
| #if __GLASGOW_HASKELL__ >= 800 | ||
| findIndex :: (HasCallStack, Ord k) => k -> Map k a -> Int | ||
| #else | ||
| findIndex :: Ord k => k -> Map k a -> Int | ||
| #endif | ||
| findIndex = go 0 | ||
| where | ||
| go :: Ord k => Int -> k -> Map k a -> Int | ||
|
|
@@ -1477,7 +1488,11 @@ lookupIndex = go 0 | |
| -- > elemAt 1 (fromList [(5,"a"), (3,"b")]) == (5, "a") | ||
| -- > elemAt 2 (fromList [(5,"a"), (3,"b")]) Error: index out of range | ||
|
|
||
| #if __GLASGOW_HASKELL__ >= 800 | ||
| elemAt :: HasCallStack => Int -> Map k a -> (k,a) | ||
| #else | ||
| elemAt :: Int -> Map k a -> (k,a) | ||
| #endif | ||
| elemAt !_ Tip = error "Map.elemAt: index out of range" | ||
| elemAt i (Bin _ kx x l r) | ||
| = case compare i sizeL of | ||
|
|
@@ -1566,7 +1581,11 @@ splitAt i0 m0 | |
| -- > updateAt (\_ _ -> Nothing) 2 (fromList [(5,"a"), (3,"b")]) Error: index out of range | ||
| -- > updateAt (\_ _ -> Nothing) (-1) (fromList [(5,"a"), (3,"b")]) Error: index out of range | ||
|
|
||
| #if __GLASGOW_HASKELL__ >= 800 | ||
| updateAt :: HasCallStack => (k -> a -> Maybe a) -> Int -> Map k a -> Map k a | ||
| #else | ||
| updateAt :: (k -> a -> Maybe a) -> Int -> Map k a -> Map k a | ||
| #endif | ||
|
||
| updateAt f !i t = | ||
| case t of | ||
| Tip -> error "Map.updateAt: index out of range" | ||
|
|
@@ -1588,7 +1607,11 @@ updateAt f !i t = | |
| -- > deleteAt 2 (fromList [(5,"a"), (3,"b")]) Error: index out of range | ||
| -- > deleteAt (-1) (fromList [(5,"a"), (3,"b")]) Error: index out of range | ||
|
|
||
| #if __GLASGOW_HASKELL__ >= 800 | ||
| deleteAt :: HasCallStack => Int -> Map k a -> Map k a | ||
| #else | ||
|
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. Same question here. |
||
| deleteAt :: Int -> Map k a -> Map k a | ||
| #endif | ||
| deleteAt !i t = | ||
| case t of | ||
| Tip -> error "Map.deleteAt: index out of range" | ||
|
|
@@ -1624,7 +1647,11 @@ lookupMin (Bin _ k x l _) = Just $! lookupMinSure k x l | |
| -- > findMin (fromList [(5,"a"), (3,"b")]) == (3,"b") | ||
| -- > findMin empty Error: empty map has no minimal element | ||
|
|
||
| #if __GLASGOW_HASKELL__ >= 800 | ||
| findMin :: HasCallStack => Map k a -> (k,a) | ||
| #else | ||
| findMin :: Map k a -> (k,a) | ||
| #endif | ||
| findMin t | ||
| | Just r <- lookupMin t = r | ||
| | otherwise = error "Map.findMin: empty map has no minimal element" | ||
|
|
@@ -1649,7 +1676,11 @@ lookupMax :: Map k a -> Maybe (k, a) | |
| lookupMax Tip = Nothing | ||
| lookupMax (Bin _ k x _ r) = Just $! lookupMaxSure k x r | ||
|
|
||
| #if __GLASGOW_HASKELL__ >= 800 | ||
| findMax :: HasCallStack => Map k a -> (k,a) | ||
| #else | ||
| findMax :: Map k a -> (k,a) | ||
| #endif | ||
| findMax t | ||
| | Just r <- lookupMax t = r | ||
| | otherwise = error "Map.findMax: empty map has no maximal element" | ||
|
|
@@ -3866,7 +3897,11 @@ maxViewSure = go | |
| -- > deleteFindMin (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((3,"b"), fromList[(5,"a"), (10,"c")]) | ||
| -- > deleteFindMin Error: can not return the minimal element of an empty map | ||
|
|
||
| #if __GLASGOW_HASKELL__ >= 800 | ||
| deleteFindMin :: HasCallStack => Map k a -> ((k,a),Map k a) | ||
| #else | ||
| deleteFindMin :: Map k a -> ((k,a),Map k a) | ||
| #endif | ||
| deleteFindMin t = case minViewWithKey t of | ||
| Nothing -> (error "Map.deleteFindMin: can not return the minimal element of an empty map", Tip) | ||
| Just res -> res | ||
|
|
@@ -3876,7 +3911,11 @@ deleteFindMin t = case minViewWithKey t of | |
| -- > deleteFindMax (fromList [(5,"a"), (3,"b"), (10,"c")]) == ((10,"c"), fromList [(3,"b"), (5,"a")]) | ||
| -- > deleteFindMax empty Error: can not return the maximal element of an empty map | ||
|
|
||
| #if __GLASGOW_HASKELL__ >= 800 | ||
| deleteFindMax :: HasCallStack => Map k a -> ((k,a),Map k a) | ||
| #else | ||
| deleteFindMax :: Map k a -> ((k,a),Map k a) | ||
| #endif | ||
| deleteFindMax t = case maxViewWithKey t of | ||
| Nothing -> (error "Map.deleteFindMax: can not return the maximal element of an empty map", Tip) | ||
| Just res -> res | ||
|
|
||
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.
Does the call stack grow through the recursion here or elsewhere? If so, that's a big problem. You can check the Core to be sure. We know there are no
Nils except at the root, but GHC does not! If the stacks build, you'll need to restructure the functions to fix that. Watch out for performance. If the times for the current benchmarks exercising these functions are too short to trust, consider adding more benchmarks.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.
Wow, yes it does. I didn't realize it would do that. The fix is to use an internal
gofunction. I'll update the PR with that in a moment.On a related note, I realized that my
HasCallStackforMap.!was wrong becauseMap.!callsfindwhich actually throws the error. Is there a reason it usesfindrather thanlookup? My inclination is to removefindaltogether (it's only used by!and looks identical other than theMaybewrapper) and replace withlookup---then!can callerroritself, which should then makeHasCallStackwork the way we want.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.
Oh, I just noticed the
[Note: Local 'go' functions and capturing]-- I'll read that and try to make sure I'm not doing anything stupid.