{-# LANGUAGE MultiParamTypeClasses
,FunctionalDependencies
,FlexibleInstances #-}{-
Copyright (C) 2007 John Goerzen <jgoerzen@complete.org>
All rights reserved.
For license and copyright information, see the file COPYRIGHT
-}{- |
Module : Data.ListLike.FoldableLL
Copyright : Copyright (C) 2007 John Goerzen
License : BSD3
Maintainer : John Lato <jwlato@gmail.com>
Stability : provisional
Portability: portable
Generic tools for data structures that can be folded.
Written by John Goerzen, jgoerzen\@complete.org
-}moduleData.ListLike.FoldableLL(-- * FoldableLL ClassFoldableLL(..),-- * Utilitiesfold,foldMap,foldM,sequence_,mapM_)whereimportPreludehiding(foldl,foldr,foldr1,sequence_,mapM_)importqualifiedData.FoldableasFimportData.MonoidimportData.MaybeimportqualifiedData.ListasL{- | This is the primary class for structures that are to be considered
foldable. A minimum complete definition provides 'foldl' and 'foldr'.
Instances of 'FoldableLL' can be folded, and can be many and varied.
These functions are used heavily in "Data.ListLike". -}classFoldableLLfullitem|full->itemwhere{- | Left-associative fold -}foldl::(a->item->a)->a->full->a{- | Strict version of 'foldl'. -}foldl'::(a->item->a)->a->full->a-- This implementation from Data.Foldablefoldl'faxs=foldrf'idxsawheref'xkz=k$!fzx-- | A variant of 'foldl' with no base case. Requires at least 1-- list element.foldl1::(item->item->item)->full->item-- This implementation from Data.Foldablefoldl1fxs=fromMaybe(error"fold1: empty structure")(foldlmfNothingxs)wheremfNothingy=Justymf(Justx)y=Just(fxy){- | Right-associative fold -}foldr::(item->b->b)->b->full->b-- | Strict version of 'foldr'foldr'::(item->b->b)->b->full->b-- This implementation from Data.Foldablefoldr'faxs=foldlf'idxsawheref'kxz=k$!fxz-- | Like 'foldr', but with no starting valuefoldr1::(item->item->item)->full->item-- This implementation from Data.Foldablefoldr1fxs=fromMaybe(error"foldr1: empty structure")(foldrmfNothingxs)wheremfxNothing=Justxmfx(Justy)=Just(fxy){- | Combine the elements of a structure using a monoid.
@'fold' = 'foldMap' id@ -}fold::(FoldableLLfullitem,Monoiditem)=>full->itemfold=foldMapid{- | Map each element to a monoid, then combine the results -}foldMap::(FoldableLLfullitem,Monoidm)=>(item->m)->full->mfoldMapf=foldr(mappend.f)memptyinstanceFoldableLL[a]awherefoldl=L.foldlfoldl1=L.foldl1foldl'=L.foldl'foldr=L.foldrfoldr1=L.foldr1foldr'=F.foldr'{-
instance (F.Foldable f) => FoldableLL (f a) a where
foldl = F.foldl
foldl1 = F.foldl1
foldl' = F.foldl'
foldr = F.foldr
foldr1 = F.foldr1
foldr' = F.foldr'
-}-- Based on http://stackoverflow.com/a/12881193/1333025{- | Monadic version of left fold, similar to 'Control.Monad.foldM'. -}foldM::(Monadm,FoldableLLfullitem)=>(a->item->ma)->a->full->mafoldMfzxs=foldr(\xresta->fax>>=rest)returnxsz{- | A map in monad space, discarding results. -}mapM_::(Monadm,FoldableLLfullitem)=>(item->mb)->full->m()mapM_func=foldr((>>).func)(return()){- | Evaluate each action, ignoring the results.
Same as @'mapM_' 'id'@. -}sequence_::(Monadm,FoldableLLfull(mitem))=>full->m()sequence_=mapM_id