- haskpy.typeclasses.foldable.Foldable
Foldable¶
- class Foldable[source]¶
Bases:
TypeFoldable typeclass
Strictly minimal complete definition:
fold_maporfoldlorfoldr
Recommended minimal complete definition:
foldlfoldrto_iterlength
If default implementation is used for any of those, a performance warning is raised.
It is very strongly recommended to implement both
foldlandfoldrbecause the default implementations won’t scale up in Python. Also,to_iteris strongly recommended as many other methods rely on that and the default implementation is slow.Note that
foldlandfoldrare sequential, butfold_mapcould be parallelized because it uses monoids. Thus, if parallelized implementation is needed, then alsofold_mapshould be implemented.The default implementations are defined in circular fashion so that only one of
fold_map,foldlandfoldris strictly needed:fold_mapusesfoldl, which usesfoldr, which usesfold_map. But as said, instance implementations of at least bothfoldlandfoldrare strongly recommended.Examples
In Haskell, Data.Set is Foldable, but not a Functor
- fold_map(monoid, f)[source]¶
Monoid m => t a -> (a -> m) -> m (ignoring
monoidargument)The default implementation is based on
foldl(or, if not implemented, recursively onfoldr). Thus, all possibilities for parallelism is lost.monoidis the monoidic class of the values inside the foldable. It is only used to determine the identity value.
- foldl(combine, initial)[source]¶
t a -> (b -> a -> b) -> b -> b
The default implementation is based on
foldr(or, if not implemented, recursively onfold_map). Either way, the default implementation doesn’t scale up well, so an instance implementation is strongly recommended.Intuition:
equivalent to for-loop on lists
never works on infinite lists (so not possible to implement
mapin terms offoldl)
References
- foldr(combine, initial)[source]¶
t a -> (a -> b -> b) -> b -> b
Warning
The default is very poor in Python. It is strongly recommended to provide an instance implementation for this.
The default implementation uses
fold_mapby utilizing (endo)function monoid:empty :: b -> b
append :: (b -> b) -> (b -> b) -> (b -> b)
One can see
combinefunction as a transformation to this monoid:combine :: a -> (b -> b)
Then, just use endofunction monoid to compose all those
b -> bendofunctions into a single endofunctionb -> b. Finally, apply this function to the initial value.Intuition:
performs constructor replacement
may work on infinite lists
doesn’t “calculate from the right” but associates to the right (otherwise it couldn’t work on infinite lists)
References
- length()[source]¶
t a -> int
The default implementation isn’t very efficient as it traverses through the iterator.
- to_iter()[source]¶
t a -> Iter a
Instead of to_list (as in Haskell), let’s provide to_iter. With iterables, we can write efficient implementations for many other methods (e.g., sum, elem) even for large or sometimes infinite foldables.
The default implementation isn’t very efficient as it uses folding to construct the iterator.