From 8ae6bec9ff37efc2823b81abca4447b86fea4889 Mon Sep 17 00:00:00 2001 From: raymoo Date: Sat, 13 Jun 2015 12:16:01 -0700 Subject: [PATCH 1/4] Try to make inlining earlier for some At instances --- src/Control/Lens/At.hs | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/Control/Lens/At.hs b/src/Control/Lens/At.hs index 5869a63ce..b5ebc0093 100644 --- a/src/Control/Lens/At.hs +++ b/src/Control/Lens/At.hs @@ -391,49 +391,55 @@ sans k m = m & at k .~ Nothing {-# INLINE sans #-} instance At (Maybe a) where - at () f = f + at () = \f -> f {-# INLINE at #-} instance At (IntMap a) where - at k f m = f mv <&> \r -> case r of + at k = \f m -> + let mv = IntMap.lookup k m + in f mv <&> \r -> case r of Nothing -> maybe m (const (IntMap.delete k m)) mv Just v' -> IntMap.insert k v' m - where mv = IntMap.lookup k m {-# INLINE at #-} instance Ord k => At (Map k a) where - at k f m = f mv <&> \r -> case r of + at k = \f m -> + let mv = Map.lookup k m + in f mv <&> \r -> case r of Nothing -> maybe m (const (Map.delete k m)) mv Just v' -> Map.insert k v' m - where mv = Map.lookup k m {-# INLINE at #-} instance (Eq k, Hashable k) => At (HashMap k a) where - at k f m = f mv <&> \r -> case r of + at k = \f m -> + let mv = HashMap.lookup k m + in f mv <&> \r -> case r of Nothing -> maybe m (const (HashMap.delete k m)) mv Just v' -> HashMap.insert k v' m - where mv = HashMap.lookup k m {-# INLINE at #-} instance At IntSet where - at k f m = f mv <&> \r -> case r of + at k = \f m -> + let mv = if IntSet.member k m then Just () else Nothing + in f mv <&> \r -> case r of Nothing -> maybe m (const (IntSet.delete k m)) mv Just () -> IntSet.insert k m - where mv = if IntSet.member k m then Just () else Nothing {-# INLINE at #-} instance Ord k => At (Set k) where - at k f m = f mv <&> \r -> case r of + at k = \f m -> + let mv = if Set.member k m then Just () else Nothing + in f mv <&> \r -> case r of Nothing -> maybe m (const (Set.delete k m)) mv Just () -> Set.insert k m - where mv = if Set.member k m then Just () else Nothing {-# INLINE at #-} instance (Eq k, Hashable k) => At (HashSet k) where - at k f m = f mv <&> \r -> case r of + at k = \f m -> + let mv = if HashSet.member k m then Just () else Nothing + in f mv <&> \r -> case r of Nothing -> maybe m (const (HashSet.delete k m)) mv Just () -> HashSet.insert k m - where mv = if HashSet.member k m then Just () else Nothing {-# INLINE at #-} From a808f985a748a67d9a99f29b55a161e609bc584b Mon Sep 17 00:00:00 2001 From: raymoo Date: Sat, 13 Jun 2015 12:33:53 -0700 Subject: [PATCH 2/4] Argument moving for Contains instances --- src/Control/Lens/At.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Control/Lens/At.hs b/src/Control/Lens/At.hs index b5ebc0093..da1609be8 100644 --- a/src/Control/Lens/At.hs +++ b/src/Control/Lens/At.hs @@ -130,17 +130,17 @@ class Contains m where contains :: Index m -> Lens' m Bool instance Contains IntSet where - contains k f s = f (IntSet.member k s) <&> \b -> + contains k = \f s -> f (IntSet.member k s) <&> \b -> if b then IntSet.insert k s else IntSet.delete k s {-# INLINE contains #-} instance Ord a => Contains (Set a) where - contains k f s = f (Set.member k s) <&> \b -> + contains k = \f s -> f (Set.member k s) <&> \b -> if b then Set.insert k s else Set.delete k s {-# INLINE contains #-} instance (Eq a, Hashable a) => Contains (HashSet a) where - contains k f s = f (HashSet.member k s) <&> \b -> + contains k = \f s -> f (HashSet.member k s) <&> \b -> if b then HashSet.insert k s else HashSet.delete k s {-# INLINE contains #-} From 1233c22169ef4e4661d4229bcf9482f63ee4c08d Mon Sep 17 00:00:00 2001 From: raymoo Date: Sat, 13 Jun 2015 18:11:39 -0700 Subject: [PATCH 3/4] Argument moving for Ixed instances --- src/Control/Lens/At.hs | 111 +++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 49 deletions(-) diff --git a/src/Control/Lens/At.hs b/src/Control/Lens/At.hs index da1609be8..910fdc128 100644 --- a/src/Control/Lens/At.hs +++ b/src/Control/Lens/At.hs @@ -184,91 +184,98 @@ ixAt i = at i . traverse type instance IxValue (e -> a) = a instance Eq e => Ixed (e -> a) where - ix e p f = p (f e) <&> \a e' -> if e == e' then a else f e' + ix e = \p f -> p (f e) <&> \a e' -> if e == e' then a else f e' {-# INLINE ix #-} type instance IxValue (Maybe a) = a instance Ixed (Maybe a) where - ix () f (Just a) = Just <$> f a - ix () _ Nothing = pure Nothing + ix () = \f ma -> case ma of + Just a -> Just <$> f a + Nothing -> pure Nothing {-# INLINE ix #-} type instance IxValue [a] = a instance Ixed [a] where - ix k f xs0 | k < 0 = pure xs0 - | otherwise = go xs0 k where - go [] _ = pure [] - go (a:as) 0 = f a <&> (:as) - go (a:as) i = (a:) <$> (go as $! i - 1) + ix k + | k < 0 = const pure + | otherwise = \f xs0 -> + let go [] _ = pure [] + go (a:as) 0 = f a <&> (:as) + go (a:as) i = (a:) <$> (go as $! i - 1) + in go xs0 k {-# INLINE ix #-} type instance IxValue (NonEmpty a) = a instance Ixed (NonEmpty a) where - ix k f xs0 | k < 0 = pure xs0 - | otherwise = go xs0 k where - go (a:|as) 0 = f a <&> (:|as) - go (a:|as) i = (a:|) <$> ix (i - 1) f as + ix k + | k < 0 = const pure + | otherwise = \f xs0 -> + let go (a:|as) 0 = f a <&> (:|as) + go (a:|as) i = (a:|) <$> ix (i - 1) f as + in go xs0 k {-# INLINE ix #-} type instance IxValue (Identity a) = a instance Ixed (Identity a) where - ix () f (Identity a) = Identity <$> f a + ix () = \f (Identity a) -> Identity <$> f a {-# INLINE ix #-} type instance IxValue (Tree a) = a instance Ixed (Tree a) where - ix xs0 f = go xs0 where - go [] (Node a as) = f a <&> \a' -> Node a' as - go (i:is) t@(Node a as) - | i < 0 = pure t - | otherwise = Node a <$> ix i (go is) as + ix xs0 = \f -> + let go [] (Node a as) = f a <&> \a' -> Node a' as + go (i:is) t@(Node a as) + | i < 0 = pure t + | otherwise = Node a <$> ix i (go is) as + in go xs0 {-# INLINE ix #-} type instance IxValue (Seq a) = a instance Ixed (Seq a) where - ix i f m - | 0 <= i && i < Seq.length m = f (Seq.index m i) <&> \a -> Seq.update i a m - | otherwise = pure m + ix i = \f m -> + if 0 <= i && i < Seq.length m + then f (Seq.index m i) <&> \a -> Seq.update i a m + else pure m {-# INLINE ix #-} type instance IxValue (IntMap a) = a instance Ixed (IntMap a) where - ix k f m = case IntMap.lookup k m of + ix k = \f m -> case IntMap.lookup k m of Just v -> f v <&> \v' -> IntMap.insert k v' m Nothing -> pure m {-# INLINE ix #-} type instance IxValue (Map k a) = a instance Ord k => Ixed (Map k a) where - ix k f m = case Map.lookup k m of + ix k = \f m -> case Map.lookup k m of Just v -> f v <&> \v' -> Map.insert k v' m Nothing -> pure m {-# INLINE ix #-} type instance IxValue (HashMap k a) = a instance (Eq k, Hashable k) => Ixed (HashMap k a) where - ix k f m = case HashMap.lookup k m of + ix k = \f m -> case HashMap.lookup k m of Just v -> f v <&> \v' -> HashMap.insert k v' m Nothing -> pure m {-# INLINE ix #-} type instance IxValue (Set k) = () instance Ord k => Ixed (Set k) where - ix k f m = if Set.member k m + ix k = \f m -> if Set.member k m then f () <&> \() -> Set.insert k m else pure m {-# INLINE ix #-} type instance IxValue IntSet = () instance Ixed IntSet where - ix k f m = if IntSet.member k m + ix k = \f m -> if IntSet.member k m then f () <&> \() -> IntSet.insert k m else pure m {-# INLINE ix #-} type instance IxValue (HashSet k) = () instance (Eq k, Hashable k) => Ixed (HashSet k) where - ix k f m = if HashSet.member k m + ix k = \f m -> if HashSet.member k m then f () <&> \() -> HashSet.insert k m else pure m {-# INLINE ix #-} @@ -280,9 +287,10 @@ type instance IxValue (Array.Array i e) = e -- arr '//' [(i,e)] ≡ 'ix' i 'Control.Lens.Setter..~' e '$' arr -- @ instance Ix i => Ixed (Array.Array i e) where - ix i f arr - | inRange (bounds arr) i = f (arr Array.! i) <&> \e -> arr Array.// [(i,e)] - | otherwise = pure arr + ix i = \f arr -> + if inRange (bounds arr) i + then f (arr Array.! i) <&> \e -> arr Array.// [(i,e)] + else pure arr {-# INLINE ix #-} type instance IxValue (UArray i e) = e @@ -292,42 +300,47 @@ type instance IxValue (UArray i e) = e -- arr '//' [(i,e)] ≡ 'ix' i 'Control.Lens.Setter..~' e '$' arr -- @ instance (IArray UArray e, Ix i) => Ixed (UArray i e) where - ix i f arr - | inRange (bounds arr) i = f (arr Array.! i) <&> \e -> arr Array.// [(i,e)] - | otherwise = pure arr + ix i = \f arr -> + if inRange (bounds arr) i + then f (arr Array.! i) <&> \e -> arr Array.// [(i,e)] + else pure arr {-# INLINE ix #-} type instance IxValue (Vector.Vector a) = a instance Ixed (Vector.Vector a) where - ix i f v - | 0 <= i && i < Vector.length v = f (v Vector.! i) <&> \a -> v Vector.// [(i, a)] - | otherwise = pure v + ix i = \f v -> + if 0 <= i && i < Vector.length v + then f (v Vector.! i) <&> \a -> v Vector.// [(i, a)] + else pure v {-# INLINE ix #-} type instance IxValue (Prim.Vector a) = a instance Prim a => Ixed (Prim.Vector a) where - ix i f v - | 0 <= i && i < Prim.length v = f (v Prim.! i) <&> \a -> v Prim.// [(i, a)] - | otherwise = pure v + ix i = \f v -> + if 0 <= i && i < Prim.length v + then f (v Prim.! i) <&> \a -> v Prim.// [(i, a)] + else pure v {-# INLINE ix #-} type instance IxValue (Storable.Vector a) = a instance Storable a => Ixed (Storable.Vector a) where - ix i f v - | 0 <= i && i < Storable.length v = f (v Storable.! i) <&> \a -> v Storable.// [(i, a)] - | otherwise = pure v + ix i = \f v -> + if 0 <= i && i < Storable.length v + then f (v Storable.! i) <&> \a -> v Storable.// [(i, a)] + else pure v {-# INLINE ix #-} type instance IxValue (Unboxed.Vector a) = a instance Unbox a => Ixed (Unboxed.Vector a) where - ix i f v - | 0 <= i && i < Unboxed.length v = f (v Unboxed.! i) <&> \a -> v Unboxed.// [(i, a)] - | otherwise = pure v + ix i = \f v -> + if 0 <= i && i < Unboxed.length v + then f (v Unboxed.! i) <&> \a -> v Unboxed.// [(i, a)] + else pure v {-# INLINE ix #-} type instance IxValue StrictT.Text = Char instance Ixed StrictT.Text where - ix e f s = case StrictT.splitAt e s of + ix e = \f s -> case StrictT.splitAt e s of (l, mr) -> case StrictT.uncons mr of Nothing -> pure s Just (c, xs) -> f c <&> \d -> StrictT.concat [l, StrictT.singleton d, xs] @@ -335,7 +348,7 @@ instance Ixed StrictT.Text where type instance IxValue LazyT.Text = Char instance Ixed LazyT.Text where - ix e f s = case LazyT.splitAt e s of + ix e = \f s -> case LazyT.splitAt e s of (l, mr) -> case LazyT.uncons mr of Nothing -> pure s Just (c, xs) -> f c <&> \d -> LazyT.append l (LazyT.cons d xs) @@ -343,7 +356,7 @@ instance Ixed LazyT.Text where type instance IxValue StrictB.ByteString = Word8 instance Ixed StrictB.ByteString where - ix e f s = case StrictB.splitAt e s of + ix e = \f s -> case StrictB.splitAt e s of (l, mr) -> case StrictB.uncons mr of Nothing -> pure s Just (c, xs) -> f c <&> \d -> StrictB.concat [l, StrictB.singleton d, xs] @@ -352,7 +365,7 @@ instance Ixed StrictB.ByteString where type instance IxValue LazyB.ByteString = Word8 instance Ixed LazyB.ByteString where -- TODO: we could be lazier, returning each chunk as it is passed - ix e f s = case LazyB.splitAt e s of + ix e = \f s -> case LazyB.splitAt e s of (l, mr) -> case LazyB.uncons mr of Nothing -> pure s Just (c, xs) -> f c <&> \d -> LazyB.append l (LazyB.cons d xs) From a8677d855ca4e25cf864824a42315524a24603c4 Mon Sep 17 00:00:00 2001 From: raymoo Date: Sat, 13 Jun 2015 18:12:15 -0700 Subject: [PATCH 4/4] \f -> f to id --- src/Control/Lens/At.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Control/Lens/At.hs b/src/Control/Lens/At.hs index 910fdc128..055786626 100644 --- a/src/Control/Lens/At.hs +++ b/src/Control/Lens/At.hs @@ -404,7 +404,7 @@ sans k m = m & at k .~ Nothing {-# INLINE sans #-} instance At (Maybe a) where - at () = \f -> f + at () = id {-# INLINE at #-} instance At (IntMap a) where