# Not Everything is a Function in Haskell

Image Attribution:

Debian Logo: Software in the Public Interest, Inc. "The Debian Open Use Logo." 1999. Under a GNU Lesser General Public License (NOT a CC-BY 3.0 License).

Screenshot: cmus Project. "Untitled." 2013. Under a GNU General Public License v3.0 (NOT a CC-BY 3.0 License).

Logo + Screenshot: Shuang, Rimu. "Untitled." Mar 19, 2014. Under a GNU General Public License v3.0 (NOT a CC-BY 3.0 License).

### January 24, 2014

### moving, django, hakyll

A common misconception in Haskell is that everything is a function (a nice example of this is seydar on Reddit asking “Would it be heresy to henceforth call ‘y’ a function with no arguments…” here. I’m still learning Haskell, and I found at the very beginning that this was a nice way of thinking about things in Haskell. After all it tied together in a very nice way. All of a sudden it made perfect sense to pass functions to other functions because it was the *exact same thing* as passing non-function arguments. The syntax of Haskell also started making a ton of sense. If `f x y = z`

has type `a -> b -> c`

and `f x = z`

has type `a -> c`

, then naturally `f = z`

has type `c`

. So then if we have something such as `(+) 3 2`

which has type `Int -> Int -> Int`

and `3`

just has type `Int`

, then maybe it’s just a nullary function!

Aha, they’re all the same thing; they’re all functions! But they’re not. Conal Elliott has a nice article about why this isn’t the case and goes into the motivations that he thinks are behind such thinking.

I realized today, as I progress further along the road of learning Haskell, that the monadic behavior behind what we usually write using `do`

notation in Haskell, provides nice justification for why *not* everything in Haskell is a function. In particular, if, for example `3`

was a function, then in Haskell, we would represent it as `() -> Int`

, to describe the fact that it took no arguments. So what’s wrong with that? Maybe it gunks up our type system a little to say that `Int`

and `() -> Int`

can both be used to describe the same thing (even though they themselves might be distinct from one another), but Haskell’s already confusing enough right?

Well let’s take a look at the following short function

```
counter :: Int -> IO ()
counter x = putStrLn (show x) >>= (\y -> counter (x + 1))
```

Equivalently we might write

```
counter :: Int -> IO ()
counter x = do
putStrLn (show x)
counter (x + 1)
```

This function takes a number and then counts up forever, printing the result of each computation to the screen, which would yield something like the following if started at `1`

.

```
$ 1
$ 2
$ 3
$ 4
$ 5
...
```

Note that `(\y -> counter (x + 1))`

has type `() -> IO ()`

. If we were to state that `() -> a`

and `a`

can refer to the same things, then this would mean that in fact `(\y -> counter (x + 1))`

could also be said to have type `IO ()`

. Yet `counter (x + 1)`

has type `IO ()`

and it is most emphatically *not* `(\y -> counter (x + 1))`

. In fact you’ll get a type error, and for good reason, because from the perspective of monads, it makes no sense to bind a result of `IO ()`

to something of type `IO ()`

.

Hence although it might be nice mathematically for everything in Haskell to be a function (and in fact it seems there are mathematical frameworks in which this is possible), this is not the case in real life.