`Traversable`

, not the same.
]]>`Holey`

is essentially the same as `Traversable`

. Using a bleeding-edge `bifunctors`

, you get `traverseBia :: (Traversable t, Biapplicative p) => (a -> p b c) -> t a -> p (t b) (t c)`

. The implementation of that function is itself very shady: it takes advantage of structure implied by `Traversable`

that can’t be obtained `holesIn :: Traversable t => t a -> t (a, a -> t a)`

. See https://stackoverflow.com/a/49044894/1477667 for the full details. What this all means is that while it’s certainly much easier, and likely more efficient, to get holes from generics, it’s possible to get away with something weaker.
]]>Examples:

In Haskell, constructors and field names can be called like functions (they effectively are functions when used within specific contexts in the code, though they can also be used in other contexts where normal functions can’t).

In other languages, operators are built into the language and are distinct from functions. In Haskell, operators are just functions with a special syntax. (They’re actually variables, but they usually contain function values.)

In Javascript (for example), we can have: x = 5 function f() { return 5 } We can get 5 from either of these by saying ‘x’ or ‘f()’ respectively. The equivalent in Haskell is: x = 5 f = 5 And we can get 5 from either by saying ‘x’ or ‘f’ respectively. In the former case, a function that takes no arguments is distinct from a variable with a value. In the latter case, it is not. I think this thought process comes from a number of misunderstandings about the language: – They see a definition without an argument as a zero-arity function (as opposed to what’s actually happening: a definition with an argument is a variable, but the value of that variable is a function value). – Similarly, they see a definition with multiple arguments as a multi-arity function, as opposed to a 1-arity function that returns another function. – They see type syntax as a list of function argument types and a return type separated by arrows, so they figure if there’s no arrows it’s a function that just returns something and takes no arguments. – They’re probably coming from languages with no lambdas, so they don’t really understand the concept of “a variable with a function value”, and instead think of functions as a special kind of toplevel definition with a special syntax. So, when they see toplevel definitions of functions in Haskell, they conclude that all toplevel definitions are functions (since they aren’t syntactically distinct). I think this is what you mean when you talk about “definition vs function”. In my mind, this can actually be a useful (or at least non-harmful) way to think about it; a constant variable can be thought of as a zero-arity function, just as a multi-argument definition can be thought of a multi-arity function, and just as a value with parentheses around it can be thought of as a 1-tuple. None of these things are actually true, but the language is designed in such a way as to allow you to program as if they were true, for the most part.

I’m sure there are other examples that escape me at the moment. The point is, I expect people come into Haskell and read about functions, and then they read about constructors and think “oh those are functions”, and then they read about operators and think “oh those are functions too”, and then they read about variable definitions and think “those definitely also look like functions … man, it really seems like everything in Haskell is a function!”

]]>Of course, in most “OO” languages, everything is *not* an object (e.g. methods and primitives in some languages), and in Haskell everything is not a value (modules and type class instances). But, close enough