Generalize Concat and ConcatMap to Foldable

This commit is contained in:
Lysxia 2020-03-01 15:07:13 -05:00
parent 6de9f4a50d
commit dc6a3049e2
2 changed files with 33 additions and 19 deletions

View File

@ -32,11 +32,19 @@ module Fcf.Class.Foldable
, FoldrDefault_
-- * Derived operations
-- ** Predicates
, And
, Or
, All
, Any
-- ** Numbers
, Sum
-- ** Lists
, Concat
, ConcatMap
) where
import Fcf.Core (Exp, Eval)
@ -193,3 +201,28 @@ type instance Eval (Any p lst) = Eval (Foldr (Bicomap p Pure (||)) 'False lst)
-- = 6
data Sum :: t Nat -> Exp Nat
type instance Eval (Sum ns) = Eval (Foldr (+) 0 ns)
-- | Concatenate a collection of elements from a monoid.
--
-- === __Example__
--
-- For example, fold a list of lists.
--
-- > Concat :: [[a]] -> Exp [a]
--
-- >>> :kind! Eval (Concat ( '[ '[1,2], '[3,4], '[5,6]]))
-- Eval (Concat ( '[ '[1,2], '[3,4], '[5,6]])) :: [Nat]
-- = '[1, 2, 3, 4, 5, 6]
-- >>> :kind! Eval (Concat ( '[ '[Int, Maybe Int], '[Maybe String, Either Double Int]]))
-- Eval (Concat ( '[ '[Int, Maybe Int], '[Maybe String, Either Double Int]])) :: [*]
-- = '[Int, Maybe Int, Maybe String, Either Double Int]
--
data Concat :: t m -> Exp m
type instance Eval (Concat xs) = Eval (FoldMap Pure xs)
-- | Map a function and concatenate the results.
--
-- This is 'FoldMap' specialized to the list monoid.
data ConcatMap :: (a -> Exp [b]) -> t a -> Exp [b]
type instance Eval (ConcatMap f xs) = Eval (FoldMap f xs)

View File

@ -208,25 +208,6 @@ data UnList :: b -> (a -> b -> Exp b) -> [a] -> Exp b
type instance Eval (UnList y f xs) = Eval (Foldr f y xs)
-- | Concatenate a list of lists.
--
-- === __Example__
--
-- >>> :kind! Eval (Concat ( '[ '[1,2], '[3,4], '[5,6]]))
-- Eval (Concat ( '[ '[1,2], '[3,4], '[5,6]])) :: [Nat]
-- = '[1, 2, 3, 4, 5, 6]
-- >>> :kind! Eval (Concat ( '[ '[Int, Maybe Int], '[Maybe String, Either Double Int]]))
-- Eval (Concat ( '[ '[Int, Maybe Int], '[Maybe String, Either Double Int]])) :: [*]
-- = '[Int, Maybe Int, Maybe String, Either Double Int]
--
data Concat :: [[a]] -> Exp [a]
type instance Eval (Concat lsts) = Eval (Foldr (++) '[] lsts)
-- | Map a function and concatenate the results.
data ConcatMap :: (a -> Exp [b]) -> [a] -> Exp [b]
type instance Eval (ConcatMap f lst) = Eval (Concat (Eval (Map f lst)))
-- Helper for the Unfoldr.
data UnfoldrCase :: (b -> Exp (Maybe (a, b))) -> Maybe (a, b) -> Exp [a]
type instance Eval (UnfoldrCase f ('Just ab)) =