reset password
Author Message
rabbott
Posts: 1649
Posted 09:47 Oct 09, 2016 |

I plan to talk about foldr and foldl Monday, including how they are implemented. I'll show an example in which we use them to convert an integer into a list of its digits. This will be completely different from our other toDigits functions. I'll also talk a bit about lambda functions. I hope you can all attend class.

Last edited by rabbott at 09:52 Oct 09, 2016.
rabbott
Posts: 1649
Posted 19:43 Oct 11, 2016 |

In class I said that implementing foldr by using foldl was cheating and less fun. It turns out there are a couple of useful things that implementation brings out. I've added the following to the Project 5b write-up.

-- An alternative approach to implementing myFoldr is simply to reverse the third

-- argument and use myFoldl. To do that we also have to reverse the parameters of

-- the function given to myFoldl. It turns out that Haskell has a function that

-- does exactly that: flip. We will implement our own versions of both reverse and  

-- flip.

myFoldr' :: (a -> b -> b) -> b -> [a] -> b           

myFoldr' f accInit xs = myFoldl (myFlip f) accInit (myReverse xs)

 

-- The following is a naïve version of reverse. It’s naïve because (a) it is O(n^2)

-- and (b) it is not tail recursive.  It’s O(n^2) because the entire list must be

-- traversed to put each element at the end.

naiveReverse :: [t] -> [t]

naiveReverse [] = []

naiveReverse (x:xs) = naiveReverse xs ++ [x]

 

-- This is a more traditional approach to reversing a list: use an accumulator.

-- This version is tail recursive and is O(n).

myReverse1 :: [t] -> [t]

myReverse1 xs = myReverse1Aux [] xs

  where myReverse1Aux acc [] = acc

        myReverse1Aux acc (x:xs) = myReverse1Aux (x:acc) xs

 

-- But as long as we are using an accumulator, why not use foldl?

myReverse :: [t] -> [t]

myReverse xs = foldl (\acc x -> x:acc) [] xs

 

myFlip :: (a -> b -> c) -> (b -> a -> c)

myFlip f = \y x -> f x y

 

Last edited by rabbott at 19:51 Oct 11, 2016.