Learn You a Haskell explains foldl1
:
The foldl1 and foldr1 functions work much like foldl and foldr, only you don't need to provide them with an explicit starting value. They assume the first (or last) element of the list to be the starting value and then start the fold with the element next to it. ...
Because they depend on the lists they fold up having at least one element, they cause runtime errors if called with empty lists
I figured its implementation is, more or less, the following:
foldl1' :: (a -> a -> a) -> [a] -> a
foldl1' f ys = foldl f (head ys) (tail ys)
But, this potential run-time error troubles me.
Why not implement foldlOption
in the following way?
foldlOption :: (a -> a -> a) -> [a] -> Maybe a
foldlOption f [] = Nothing
foldlOption f ys = Just (foldl f (head ys) (tail ys))
REPL
*Main> foldlOption (\acc elem -> if (elem > acc) then elem else acc) []
Nothing
-- find max
*Main> foldlOption (\acc elem -> if (elem > acc) then elem else acc) [1,100,2,3]
Just 100
EDITED
Updated foldl1
's and foldlOption
's definitions to use tail ys
as the last argument to foldl
, not ys
per Lee Duhem's correction. .
There's actually no good reason why not to do this. Many of the functions in Haskell's prelude like head
, tail
, init
, and many many others fail unnecessarily.
It would be much nicer for them to explicitly note their failure in the types, but that's unfortunately just not what happened when Prelude was standardized and we can't very well change several core functions like head
!
Nowadays I recommend simply not using many of these functions and opting for pattern matching, or Gabriel Gonzalez's errors library which provides alternate versions of prelude's partial functions which fail properly.
For example in Control.Error.Safe
there's
foldl1Err :: e -> (a -> a -> a) -> [a] -> Either e a
and errors also exports safe, a similar library with Maybe
's which has the function
foldl1May :: (a -> a -> a) -> [a] -> Maybe a
exactly like what you wanted :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With