From dc6a3049e201597337727e6e0be905d1a809af94 Mon Sep 17 00:00:00 2001 From: Lysxia Date: Sun, 1 Mar 2020 15:07:13 -0500 Subject: [PATCH] Generalize Concat and ConcatMap to Foldable --- src/Fcf/Class/Foldable.hs | 33 +++++++++++++++++++++++++++++++++ src/Fcf/Data/List.hs | 19 ------------------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/Fcf/Class/Foldable.hs b/src/Fcf/Class/Foldable.hs index 631365b..d10ba1a 100644 --- a/src/Fcf/Class/Foldable.hs +++ b/src/Fcf/Class/Foldable.hs @@ -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) diff --git a/src/Fcf/Data/List.hs b/src/Fcf/Data/List.hs index ab90a57..9f482f0 100644 --- a/src/Fcf/Data/List.hs +++ b/src/Fcf/Data/List.hs @@ -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)) =