aboutsummaryrefslogtreecommitdiff
path: root/haddock-api/src/Haddock/Syb.hs
diff options
context:
space:
mode:
authorDoug Wilson <dwilson@ricoh.co.nz>2017-05-28 05:54:53 +1200
committerAlex Biehl <alexbiehl@gmail.com>2017-05-27 19:54:53 +0200
commit506f614402192bd7b6a9a608e925a01b373b2bdc (patch)
treeed6f2df5eb20543be3a88f76ea8ec6ab4e448f87 /haddock-api/src/Haddock/Syb.hs
parentc836dd4cb47d457b066b51b61a08f583a8c4466e (diff)
Improve Syb code (#621)
Specialize.hs and Ast.hs are modified to have their Syb code not recurse into Name or Id in HsSyn types. Specialize.hs is refactored to have fewer calls to Syb functions. Syb.hs has some foldl calls replaced with foldl' calls. There is still a lot of performance on the floor of Ast.hs. The RenamedSource is traversed many times, and lookupBySpan is very inefficient. everywhereBut and lookupBySpan dominate the runtime whenever --hyperlinked-source is passed.
Diffstat (limited to 'haddock-api/src/Haddock/Syb.hs')
-rw-r--r--haddock-api/src/Haddock/Syb.hs55
1 files changed, 49 insertions, 6 deletions
diff --git a/haddock-api/src/Haddock/Syb.hs b/haddock-api/src/Haddock/Syb.hs
index 4847e486..7e34ae8c 100644
--- a/haddock-api/src/Haddock/Syb.hs
+++ b/haddock-api/src/Haddock/Syb.hs
@@ -1,8 +1,11 @@
{-# LANGUAGE Rank2Types #-}
-
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE ScopedTypeVariables #-}
module Haddock.Syb
- ( everything, everythingWithState, everywhere
+ ( everything, everythingButType, everythingWithState
+ , everywhere, everywhereButType
, mkT
, combine
) where
@@ -10,16 +13,41 @@ module Haddock.Syb
import Data.Data
import Control.Applicative
+import Data.Maybe
+import Data.Foldable
+-- | Returns true if a == t.
+-- requires AllowAmbiguousTypes
+isType :: forall a b. (Typeable a, Typeable b) => b -> Bool
+isType _ = isJust $ eqT @a @b
-- | Perform a query on each level of a tree.
--
-- This is stolen directly from SYB package and copied here to not introduce
-- additional dependencies.
-everything :: (r -> r -> r) -> (forall a. Data a => a -> r)
+everything :: (r -> r -> r)
+ -> (forall a. Data a => a -> r)
-> (forall a. Data a => a -> r)
-everything k f x = foldl k (f x) (gmapQ (everything k f) x)
+everything k f x = foldl' k (f x) (gmapQ (everything k f) x)
+
+-- | Variation of "everything" with an added stop condition
+-- Just like 'everything', this is stolen from SYB package.
+everythingBut :: (r -> r -> r)
+ -> (forall a. Data a => a -> (r, Bool))
+ -> (forall a. Data a => a -> r)
+everythingBut k f x = let (v, stop) = f x
+ in if stop
+ then v
+ else foldl' k v (gmapQ (everythingBut k f) x)
+-- | Variation of "everything" that does not recurse into children of type t
+-- requires AllowAmbiguousTypes
+everythingButType ::
+ forall t r. (Typeable t)
+ => (r -> r -> r)
+ -> (forall a. Data a => a -> r)
+ -> (forall a. Data a => a -> r)
+everythingButType k f = everythingBut k $ (,) <$> f <*> isType @t
-- | Perform a query with state on each level of a tree.
--
@@ -31,8 +59,7 @@ everythingWithState :: s -> (r -> r -> r)
-> (forall a. Data a => a -> r)
everythingWithState s k f x =
let (r, s') = f x s
- in foldl k r (gmapQ (everythingWithState s' k f) x)
-
+ in foldl' k r (gmapQ (everythingWithState s' k f) x)
-- | Apply transformation on each level of a tree.
--
@@ -40,6 +67,22 @@ everythingWithState s k f x =
everywhere :: (forall a. Data a => a -> a) -> (forall a. Data a => a -> a)
everywhere f = f . gmapT (everywhere f)
+-- | Variation on everywhere with an extra stop condition
+-- Just like 'everything', this is stolen from SYB package.
+everywhereBut :: (forall a. Data a => a -> Bool)
+ -> (forall a. Data a => a -> a)
+ -> (forall a. Data a => a -> a)
+everywhereBut q f x
+ | q x = x
+ | otherwise = f (gmapT (everywhereBut q f) x)
+
+-- | Variation of "everywhere" that does not recurse into children of type t
+-- requires AllowAmbiguousTypes
+everywhereButType :: forall t . (Typeable t)
+ => (forall a. Data a => a -> a)
+ -> (forall a. Data a => a -> a)
+everywhereButType = everywhereBut (isType @t)
+
-- | Create generic transformation.
--
-- Another function stolen from SYB package.