module Language.Haskell.Formatter.Toolkit.Visit
(findJust, orderByKey, compose, halfZipWith,
mapAccumulateLeftWithCreation)
where
import qualified Data.Foldable as Foldable
import qualified Data.List as List
import qualified Data.Maybe as Maybe
import qualified Data.Monoid as Monoid
import qualified Data.Ord as Ord
import qualified Data.Traversable as Traversable
findJust :: (Functor t, Foldable.Foldable t) => (a -> Maybe b) -> t a -> Maybe b
findJust function = Foldable.asum . fmap function
compose :: Foldable.Foldable t => t (a -> a) -> a -> a
compose = Monoid.appEndo . Foldable.foldMap Monoid.Endo
orderByKey :: Ord b => (a -> b) -> [a] -> [a]
orderByKey = List.sortBy . Ord.comparing
halfZipWith ::
(Traversable.Traversable t, Foldable.Foldable f) =>
(a -> b -> c) -> t a -> f b -> Maybe (t c)
halfZipWith merge base extension = Traversable.sequenceA zippedMaybe
where (_, zippedMaybe) = Traversable.mapAccumL process extensionList base
process [] _ = ([], Nothing)
process (extensionElement : list) baseElement
= (list, Just $ merge baseElement extensionElement)
extensionList = Foldable.toList extension
mapAccumulateLeftWithCreation ::
Traversable.Traversable t =>
(a -> b -> (a, c)) ->
(b -> a) -> t b -> (Maybe a, t c)
mapAccumulateLeftWithCreation process createBase
= Traversable.mapAccumL processMaybe Nothing
where processMaybe maybeBefore element = (Just after, element')
where (after, element') = process before element
before = Maybe.fromMaybe (createBase element) maybeBefore