Skip to content

Instantly share code, notes, and snippets.

@kspeakman
Created February 14, 2018 21:51
Show Gist options
  • Save kspeakman/cc9c67d15db59c62ef6274eed1bbeac5 to your computer and use it in GitHub Desktop.
Save kspeakman/cc9c67d15db59c62ef6274eed1bbeac5 to your computer and use it in GitHub Desktop.
Fixing Elm's List folds
module ListFolds exposing (..)
{-| Alternative implementations of List.foldl and List.foldr
-- this will add the `fold` and `foldBack` functions to the List module
import ListFolds as List
List.fold (++) "" [ "Hello", " ", "World", "!" ] == "Hello World!"
-}
{-| Fold a list from the left, properly.
List.fold (++) "" [ "Hello", " ", "World", "!" ] == "Hello World!"
-- Compare to built-in `foldl`:
List.foldl (++) "" [ "Hello", " ", "World", "!" ] == "!World Hello"
-- What you actually have to do to use built-in: flip argument order
List.foldl (\a b -> b ++ a) "" [ "Hello", " ", "World", "!" ] == "Hello World!"
-}
fold : (b -> a -> b) -> b -> List a -> b
fold f b list =
List.foldl (flip f) b list
{-| Right fold with visual argument order
-- direction of processing: 4<----------3<----------2<-----------1<
List.foldBack (::) [ "Option 3", "Option 2", "Option 1" ] [ "Select an option" ]
== [ "Select an option", "Option 1", "Option 2", "Option 3" ]
-- --------------------------------v
-- Compare to built-in `foldr`: >1-/ 4<----------3<-----------2
List.foldr (::) [ "Select an option" ] [ "Option 3", "Option 2", "Option 1" ]
== [ "Select an option", "Option 1", "Option 2", "Option 3" ]
-}
foldBack : (a -> b -> b) -> List a -> b -> b
foldBack f list b =
List.foldr f b list
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment