# Pointfree Exercises in Haskell Trail

Hi, guys!

I’ve been loving the Haskell trail so far, having a great time working my way through the exercises. I’ve made my way through half of Learn you a Haskell in the last year, so these exercises have been a great way of learning my knowledge (or lack thereof to the test). As a general point of feedback, I have so far found the exercises to be right at the limit of my mental capabilities - I feel I am literally stretching my mind as I’m working through them, just scraping across the line to finish the exercise, but learning a lot on the process.

I’ve made it as far as the Pointfree Style exercise and am now throwing my hands in the air. Here’s the one that got me:

``````isDigit :: Char -> Bool
isDigit x = elem x "1234567890"
``````

How on God’s green earth am I able to rewrite this in pointfree style?

I understand that, in effect, I am trying to:

Produce a function, that when applied, calls elem with its first parameter and 1234567890 as its second parameter.

I have no idea how I would even begin doing that. As I understand currying, functions are built left to right. eg:

``````something :: a -> b -> c
``````

Is a function that takes a as its first argument, and returns a function that then takes b as its second argument, producing c.

In effect I am trying to return a function that takes an a and applies it to b. Is this even possible?

``````something :: a -> b -> c
``````

Is a function that takes a as its first argument, and returns a function that then takes b as its second argument, producing c.

Close!

It’s a function that takes a as its only argument and returns a function that takes b as its only argument. All fns in Haskell take only a single argument.

There are at least two ways to write this in point-free style. I’d prefer to use this: http://haddocks.fpcomplete.com/fp/7.8/20140916-162/base/Prelude.html#v:flip

See if you can figure that out. If not, ping me and I’ll help.

Thanks for the reply, Ben!

Yes, that’s exactly what I meant, except for the part where you used the right words in the right order to convey the correct meaning.

Yes! Flip!! How could I have been so foolish?

Forgive me, I have failed you. My dreams of a career as a Haskell-er at thoughtbot are shattered.

Thanks again, Ben.

1 Like

Next question:

The following functions are in pointfree style:

### Example One

``````--- Lispy
hasUppercaseWord = any(all(isUpper))

--- Pointfree
hasUppercaseWord = any . all \$ isUpper
``````

### Example Two

``````--- Lispy
reversewords = unwords(reverse(words))
--- Pointfree
reverseWords = unwords . reverse . words
``````

In example one, to get the correct order of precedence, we use a combination of `\$` and `.`. In the second, we use two `.`s. What gives?

While you can get rid of `(\$)`s by adding parenthesis, you can’t do the same with `(.)`. If you wanted to translate the point-free versions to “Lispy”, you’d have to do it like this:

``````hasUppercaseWord xs = any (all isUpper xs)

reverseWords xs = unwords (reverse (words xs))
``````

Here, you can see they aren’t actually that similar, which is why the point-free versions work out differently.

In the first example, the `(\$)` is actually redundant. Function application binds tightest in Haskell, so just putting `all` and `isUpper` next to each other is enough to form a function that accepts a list and returns `True` if all elements are upper-case. This can then be composed with `any` using `(.)`.

``````hasUppercaseWord = any . all isUpper
``````

This is similar to something like:

``````secondElement = head . drop 1
``````

In the second example, `words` is not an argument to `reverse` – that wouldn’t make sense. So there’s no application (implied or made explicit by `(\$)`), you just compose each function with `(.)`.

1 Like

Brilliant answer, @pat. Thank you - this helps a lot.

As a point of general feedback, I feel I struggle with the pointfree exercises because I can’t clearly see with my eyes where each function ends and begins (eg. what’s an argument and what’s the next function) because the function names are all quite unfamiliar to me. I guess this is just a familiarity thing that will go away with time!

I’ve bought Maybe Haskell last night, and this is helping a lot more too. In all honesty, I feel as if I skimmed over too much of Learn you a Haskell as it was perhaps more dense than I gave it credit for. I’m paying for that now.

Nice. I really enjoyed it. I suspect you will too.