packages feed

composite-ix-0.0.1.0: src/Composite/Ix/List.hs

module Composite.Ix.List (groupBy, groupBy', groupBy'') where

import           Composite.Record
import           Control.Lens
import qualified Data.Map         as M
import           Data.Proxy
import           Data.Vinyl       hiding (rlens, rlens')
import           Prelude

-- | Group a list of records by a subtype of the record type.
--
-- @since 0.0.1.0
groupBy :: forall ys xs f.
           (ys ⊆ xs)
        => Ord (Rec f ys)
        => [Rec f xs]
        -> M.Map (Rec f ys) [Rec f xs]
groupBy xs = M.fromListWith (<>) $ fmap (\x -> (rcast x, [x])) xs

-- | Group a list of records by a single field.
--
-- @since 0.0.1.0
groupBy' :: forall k s y xs.
            k ~ (s :-> y)
         => k ∈ xs
         => Ord y
         => [Record xs]
         -> M.Map y [Record xs]
groupBy' xs = M.fromListWith (<>) $ fmap (\x -> (view (rlens (Proxy @(s :-> y))) x, [x])) xs

-- | Group a list of records by a single field (HKD).
--
-- @since 0.0.1.0
groupBy'' :: forall k s y xs f.
             k ~ (s :-> y)
          => k ∈ xs
          => Functor f
          => Ord (f y)
          => [Rec f xs]
          -> M.Map (f y) [Rec f xs]
groupBy'' xs = M.fromListWith (<>) $ fmap (\x -> (view (rlens' (Proxy @(s :-> y))) x, [x])) xs