Defunctionalization is nice for higher order functions where it is completely necessary to avoid runtime support, but in some cases it's favourable to use function pointers instead (since they don't generate huge code bloat for certain scenarios, i.e.):
data Foo a = Foo (a -> Int)
Under what conditions is it safe to implement higher order calls using function pointers instead of reducing them to huge switch tables of static calls?
My initial thought is that it has something to do with known arity.
map :: (a -> b) -> [a] -> [b]
, the arity of the first argument is not actually known since it could be partially applied. i.e., it could be used outside the current module likemap (transform 1 2 3 4) [1..5]
or justmap (+1) [1..5]
. In both cases the type isa -> b
but the arity is different. $\endgroup$ – kvanbere May 18 '14 at 11:32