Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get simpler but equivalent version of a Haskell expression

Tags:

haskell

Although I have been learning Haskell for some time, there is one common problem I run into constantly. Let's take this expression as an example:

e f $ g . h i . j

One may wonder, given $ and . from Prelude, what are type constraints on e or h for expression to be valid?

Is it possible to get a 'simpler' but equivalent representation? For me, 'simpler' would be one that uses parentheses everywhere and eliminates need to define operator precedence rules.

If not, which Haskell report sections do I need to read to have complete picture?

This might be relevant for many novice Haskell programmers. I know many programmers that add parentheses so that they do not need to memorize (or understand) precedence tables like this one: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

like image 300
Rumca Avatar asked Nov 11 '22 17:11

Rumca


1 Answers

Is it possible to get a 'simpler' but equivalent representation? Of course, this is called parsing, and is done by compilers, interpreters, etc.

90% of the time, all you need to remember is how $ , . and function application f x work together. This is because $ and function application are really simple - they bind the loosest and tightest respectively - they are like addition and the exponent in bodmas.

From your example

e f $ g . h i . j

the function applications bind first, so we have

(e f) $ g . (h i) . j

Function application is left associative so

f g h ==> ((f g) h)

You may have to google currying to understand why the above can be used like foo(a, b) in other languages.

In the next step do everything in the middle - I just use brackets or a table to remember this bit, it's usually straightforward. For example there are several operators like >> and >>= that are used at the same time when you are working with monads. I just add brackets when ghc complains.

So no we have

(e f) $ (g . ((h i) . j))

The order of the brackets doesn't matter as function composition is associative, however Haskell makes it right associative.

So then we have

((e f) (g . ((h i) . j)))

The above (simple) example demonstrates why those operators exist in the first place.

like image 110
user3125280 Avatar answered Nov 15 '22 07:11

user3125280