The issue is exactly that fun c -> map xs c
is not the same as map xs
. They have the same "meaning" in some sense, but their runtime semantics are different. In the latter case, evaluating the expression results in an immediate call to the map
function with xs
as an argument (returning another function as the result). On the other hand, evaluating fun c -> map xs c
does not result in an immediate call to map
! The call to map
is delayed until the resulting function is actually applied. This is the critical difference that prevents a stack overflow.
Regarding your other questions, I can't quite make out what you're asking in your second question. For your third question, the compiler has inferred the most general type possible for Bind
. You're right that the traditional type that you might expect is more specific than this, but it's not really a problem that you can call Bind
in a wider set of contexts than is strictly necessary. And if you really want a more specific type, you can always add annotations to constrain the signature.