From 6dc25d79049556990b8b79918c1ca0861d91521f Mon Sep 17 00:00:00 2001 From: Fraser Tweedale Date: Thu, 28 Jul 2022 23:34:32 +1000 Subject: [PATCH] refactor some list functions Use listSelectedElementL to simplify the implementation and improve asymptotics of some list functions. Introduces some additional constraints on these functions, so this change requires a major version bump. - `listModify`: Improved asymptotics for `Seq`. Introduces `Splittable` and `Semigroup` constraint. - `listSelectedElement`: Simpler definition. Asymptotics unchanged. Introduces `Semigroup` constraint and strengthens `Foldable` constraint to `Traversable`. --- src/Brick/Widgets/List.hs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Brick/Widgets/List.hs b/src/Brick/Widgets/List.hs index 45afec0..ed32bf2 100644 --- a/src/Brick/Widgets/List.hs +++ b/src/Brick/Widgets/List.hs @@ -82,7 +82,7 @@ import Control.Applicative ((<|>)) import Data.Foldable (find, toList) import Control.Monad.Trans.State (evalState, get, put) -import Lens.Micro (Traversal', (^.), (^?), (&), (.~), (%~), _2, _head, set) +import Lens.Micro (Traversal', (^.), (^?), (&), (.~), (%~), _2, set) import Data.Functor (($>)) import Data.List.NonEmpty (NonEmpty((:|))) import Data.Maybe (fromMaybe) @@ -635,13 +635,11 @@ listSelectedElementL f l = -- listSelectedElement for 'List': O(1) -- listSelectedElement for 'Seq.Seq': O(log(min(i, n - i))) -- @ -listSelectedElement :: (Splittable t, Foldable t) +listSelectedElement :: (Splittable t, Traversable t, Semigroup (t e)) => GenericList n t e -> Maybe (Int, e) -listSelectedElement l = do - sel <- l^.listSelectedL - let (_, xs) = splitAt sel (l ^. listElementsL) - (sel,) <$> toList xs ^? _head +listSelectedElement l = + (,) <$> l^.listSelectedL <*> l^?listSelectedElementL -- | Remove all elements from the list and clear the selection. -- @@ -670,11 +668,16 @@ listReverse l = -- -- Complexity: same as 'traverse' for the container type (typically -- /O(n)/). -listModify :: (Traversable t) +-- +-- Complexity: same as 'listSelectedElementL' for the list's container type. +-- +-- @ +-- listModify for 'List': O(n) +-- listModify for 'Seq.Seq': O(log(min(i, n - i))) +-- @ +-- +listModify :: (Traversable t, Splittable t, Semigroup (t e)) => (e -> e) -> GenericList n t e -> GenericList n t e -listModify f l = - case l ^. listSelectedL of - Nothing -> l - Just j -> l & listElementsL %~ imap (\i e -> if i == j then f e else e) +listModify f = listSelectedElementL %~ f