> If I knew you write code like this, I would feel compelled during code review to squeeze my brain to try to see whether there is some library function that does what you just did.
That's because the author didn't put a type hole before declaring arguments.
zoop :: (a -> b -> b) -> b -> [a] -> b
zoop = _
<interactive>:10:8: error:
• Found hole: _ :: (a -> b -> b) -> b -> [a] -> b
Where: ‘a’, ‘b’ are rigid type variables bound by
the type signature for:
zoop :: forall a b. (a -> b -> b) -> b -> [a] -> b
at <interactive>:9:1-38
• In the expression: _
In an equation for ‘zoop’: zoop = _
• Relevant bindings include
zoop :: (a -> b -> b) -> b -> [a] -> b
(bound at <interactive>:10:1)
Valid hole fits include
zoop :: (a -> b -> b) -> b -> [a] -> b
(bound at <interactive>:10:1)
foldr :: forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
with foldr @[] @a @b
(imported from ‘Prelude’
(and originally defined in ‘Data.Foldable’))
Here, GHC has figured out that, yes, `zoop` is in fact directly equivalent to `foldr`. And it'll do this with all other holes involved in the iterative type hole development process. So, you don't have to worry about whether there is some library function that does what the author did. GHC will do that for you.