Skip to content

Instantly share code, notes, and snippets.

@kingparra
Created November 30, 2020 01:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kingparra/e5aeac3f540ef2e2172be9f16cf15b8c to your computer and use it in GitHub Desktop.
Save kingparra/e5aeac3f540ef2e2172be9f16cf15b8c to your computer and use it in GitHub Desktop.
reverse foldr implementaion evaluation steps
-- So I found this cool implementation of reverse that uses foldr,
-- but how does it work?
rev l = foldr (\x r -> r . (x:)) id l []
{-
rev [1,2,3,4]
1:2:3:4:[]
1:2:3:4:id -- [] is replaced with our z value, id.
-- then cons is replaced with f, (\x r -> r . (x:))
-- Parameter x is the thing to the left of the cons operator, it's first
-- argument 4. Paramter r is the second argument, id.
1:2:3:(id . (4:))
-- Now our second argument is (id . (4:))
1:2:((id . (4:)) . (3:))
-- and so on...
1:(((id . (4:)) . (3:)) . (2:))
((((id . (4:)) . (3:)) . (2:)) . (1:))
((((id . (4:)) . (3:)) . (2:)) . (1:)) []
-- I got confused here so I asked on IRC
--
-- <justsomeguy> I found this reverse function that is implemented in
-- terms of foldr “rev l = foldr (\x r -> r . (x:)) id l []”, but am
-- having a hard time figuring out what the evaluation steps are. What
-- happens after I get to “((((id . (4:)) . (3:)) . (2:)) . (1:)) []”?
-- * justsomeguy thinks he misunderstands what the composition operator
-- does.
-- <monochrom> id . (4 :) = (4 :)
-- <monochrom> (4 :) . (3 :) = (\r -> 4 : 3 : r)
-- <monochrom> I think you can do the rest.
-- Oh, of course, I forgot that there's an implicit parameter awaiting an
-- argument at the end! id was only there to build up the call stack.
((((4:)) . (3:)) . (2:)) . (1:)) []
((((4:(3:)) . (2:)) . (1:)) []
(4:(3:(2:)) . (1:)) []
(4:(3:(2:(1:)))) []
(4:(3:(2:(1:[]))))
4:3:2:1:[]
[4,3,2,1]
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment