User Tools

Site Tools


codesnippets:folds

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
codesnippets:folds [2021/04/07 10:44] f2b216codesnippets:folds [2025/10/08 00:48] (current) – external edit 127.0.0.1
Line 263: Line 263:
 "zyxwvutsrqponmlkjihgfedcba" "zyxwvutsrqponmlkjihgfedcba"
 </code> </code>
-    * NOTE: Parameter order of function (:) needed to be flipped to ''[a] -> b -> [a]'' from ''b -> [a] -> [a]''.+    * NOTE: Parameter order of function (:) needed to be flipped to ''[a] -> b -> [a]'' from ''b -> [a] -> [a]'', and would not compile because of type mismatch.
   * example, using foldl':<code Haskell>   * example, using foldl':<code Haskell>
 import qualified Data.List as L import qualified Data.List as L
Line 282: Line 282:
 "zyxwvutsrqponmlkjihgfedcba" "zyxwvutsrqponmlkjihgfedcba"
 </code> </code>
-    * NOTE: Parameter order of function (:) needed to be flipped like for foldl.+    * NOTE: Parameter order of function (:) needed to be flipped as well as for foldl. 
 +  * example, with __not__ commutative operation (''-''):<code Haskell> 
 +import qualified Data.List as L 
 + 
 +main :: IO () 
 +main =  
 +    do 
 +        print lnNumbers1 
 +        print lnNumbers2 
 +        print $ f1 lnNumbers1 
 +        print $ f1 lnNumbers2 
 +        print $ f2 lnNumbers1 
 +        print $ f2 lnNumbers2 
 +        print $ f3 lnNumbers1 
 +        print $ f3 lnNumbers2 
 + 
 +lnNumbers1 = [31,7] 
 +lnNumbers2 = [31,7,3] 
 + 
 +f1 :: [Integer] -> Integer 
 +f1 ln = foldr (-) 0 ln 
 + 
 +f2 :: [Integer] -> Integer 
 +f2 ln = foldl (flip (-)) 0 ln 
 + 
 +f3 :: [Integer] -> Integer 
 +f3 ln = L.foldl' (flip (-)) 0 ln 
 +</code> 
 +    * executes with following output:<code> 
 +[31,7] 
 +[31,7,3] 
 +24 
 +27 
 +-24 
 +27 
 +-24 
 +27 
 +</code> 
 + 
 +====== Keeping order and beeing fast? ====== 
 + 
 +  * use case 
 +    * finite lists 
 +    * large lists 
 +    * order of operations to be kept as is foldr 
 +  * example, using foldr:<code Haskell> 
 +main :: IO () 
 +main =  
 +    do 
 +        print $ f1 lnNumbers1 
 +        print $ f1 lnNumbers2 
 +        print $ f1 lnNumbers3 
 + 
 +lnNumbers1 = [31,13] 
 +lnNumbers2 = [31,13,3] 
 +lnNumbers3 = [1..100000000] 
 + 
 +f1 :: [Integer] -> Integer 
 +f1 ln = foldr (-) 0 ln 
 +</code> 
 +    * executes, with output:<code> 
 +18 
 +21 
 +-50000000 
 +</code> 
 +    * executes within approximately __**15 seconds**__ on Intel(R) Core(TM) i5-8400 @ 2.80GHz 
 +    * executes using large heap space 
 +      * {{:codesnippets:heapconsumptionfoldronnoncommutativeop.png?200|}} 
 +  * example, using ''foldl'' and ''reverse'':<code Haskell> 
 +import qualified Data.List as L 
 + 
 +main :: IO () 
 +main =  
 +    do 
 +        print $ f2 lnNumbers1 
 +        print $ f2 lnNumbers2 
 +        print $ f2 lnNumbers3 
 + 
 +lnNumbers1 = [31,13] 
 +lnNumbers2 = [31,13,3] 
 +lnNumbers3 = [1..100000000] 
 + 
 +f2 :: [Integer] -> Integer 
 +f2 ln = foldlFlpRvrs (-) 0 ln 
 + 
 +foldlFlpRvrs :: (a -> b -> b) -> b -> [a] -> b 
 +foldlFlpRvrs f initial l = L.foldl' (flip f) initial (reverse l) 
 +</code> 
 +    * executes, with output:<code> 
 +18 
 +21 
 +-50000000 
 +</code> 
 +    * executes within approximately __**15 seconds**__ on Intel(R) Core(TM) i5-8400 @ 2.80GHz 
 +    * executes using large heap space 
 +      * {{:codesnippets:heapconsumptionfoldlfronnoncommutativeop.png?200|}} 
 +      * regardless of whether ''L.foldl' '' or ''foldl'' is used 
 +      * regardless of whether alternative ''reverse'' functions are implemented 
 +        * e.g.:<code Haskell> 
 +reverse' :: [a] -> [a] 
 +reverse' (x:rlx) = reverse'' [x] rlx 
 +    where 
 +        reverse'' :: [a] -> [a] -> [a] 
 +        reverse'' lxReverse [] = lxReverse 
 +        reverse'' lxReverse (x:rlx) = reverse'' (x : lxReverse) rlx 
 +</code> 
 +        * or<code Haskell> 
 +reverse' :: [a] -> [a] 
 +reverse' l = foldl (flip (:)) [] l 
 +</code> 
 +        * or<code Haskell> 
 +reverse' :: [a] -> [a] 
 +reverse' l = L.foldl' (flip (:)) [] l 
 +</code>
  
 ====== Conclusion and selection ====== ====== Conclusion and selection ======
  
-  * if the order of computation can be reverse, and if for finite lists -> use ''foldl''+  * if the order of computation can be reverse, and if for finite lists -> use ''foldl'', but....
     * if the initial value is the first and the last respectively, and there is at least one element in the list use ''foldl1 ''     * if the initial value is the first and the last respectively, and there is at least one element in the list use ''foldl1 ''
-    * if the initial value needs to be evaluated first use ''foldl' ''+    * if the initial value needs to be evaluated first -> use ''foldl' '', but...
       * if the initial value also is the first and the last respectively use ''foldl1' ''       * if the initial value also is the first and the last respectively use ''foldl1' ''
-  * if the order should be kept or if for infinite lists use -> ''foldr''+  * if the order should be kept or if for infinite lists -> use ''foldr'', but...
       * if the initial value is the first and the last respectively use ''foldr1''       * if the initial value is the first and the last respectively use ''foldr1''
  
 +
 +===== ✎ =====
 +~~DISCUSSION~~
codesnippets/folds.1617785087.txt.gz · Last modified: (external edit)

Except where otherwise noted, content on this wiki is licensed under the following license: CC0 1.0 Universal
CC0 1.0 Universal Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki