93rd day::understanding the Haskell application space
Tags: haskell, functional, 100daysofcode, computerscience
Published: 2020-10-23 14:54:53


I have been thinking much about the process of functional application, how pure functions compose, and what is the relation between operators and terms, arguments and variables, and then I realized that a tuple, which is a mathematical term for a pair, like a pair of numbers, is actually an uncurried function. What do I mean by that? I read about curried functions and have tried to visualise the curried computation flow but understanding was kinda hit and miss. I do understand the basic idea of it, a function being applied to another function, kinda like unix pipes, but have not fully understood the implications of how Haskell programs are actually build, how they evolve. My realization seemed incomplete in the sense that I still separated the two kinds of function compositions, curried and uncurried, not seeing their connection, for example like seeing a function applied on a *tuple* or any n-tuple the first thing I see is actually an uncurried function such as `f (a,b)` acting on arguments `a` and `b`. Although this is obvious now, it was not before. But what when `a` and `b` are functions, how does the computation evolve then, is currying actually the basic way a computation *computes* in Haskell? Even when we write uncurried functions, does the Haskell compiler *translate* these into curried? Often we learn concepts that build on previous knowledge and then fail to really internalize these connections, like seeing curried and uncurried functions like two sides of the same coin. 

> In mathematics and computer science, currying is the technique of converting a function that takes multiple arguments into a sequence of functions that each take a single argument.

Notice that we usually, and usually might just mean to be in the first perspective, the active part, add numbers in our heads or out loud by thinking such number plus such number ... or more passively said, like being in the third perspective, like telling someone "hey, listen to this" "add this, add this, add that". The interesting thing happens when we think of the mathematical idea of *mapping* our adding function with arguments which would be a list of such and such number like `[1,2,3,4,5]`. I guess mapping the add function could be expressed as saying: "add *those* numbers", "please". When writing or coding we usually write `(+)` sign between the numbers we would like to add, at least this is the dominant form in popular programming languages such as Python `sum = num1 + num2`, Javascript `sum = num1 + num2;` but also Haskell. Except Lisp which uses prefix function notation such as `(+ 1 2 3 4 5)`.


The other is called *infix* notation, `1 + 2 + 3 + ... n` while if we put the plus sign before the numbers we like to add we would write `(+) 1 2 3 ... n`. Now in order for Haskell compiler to understand what we mean we would have to explicitly map the plus sign to each number in the list. `map` is a function that does something to a list, called with an argument `a`, it is a *higher-order* function, meaning the argument `a` could be another function too.

The more I dive deep into this cosmic realm, the more I see how when thinking with and through Haskell, I keep seeing equivalences and how mathematical and beautiful everything seems, even though it is hard, it is only hard because it is so vast. Like a bamboo forest it covers the whole world.