Parenthesis is one of the most important syntax element in Haskell, unlike LISP, in which parenthesis is used for everything and always represent a list, Haskell use it in various different ways. This may add a little overhead for learning process. This is where the good old LISP shine, you don't have to learn about syntax since there is no syntax at all.

Represent tuples

A tuple is like a row in relational database table, it has fixed length of elements and each element has different type. In Haskell tuple represented by comma separated value surrounded by parenthesis like this

let a = ("String", 2, 3.0)
:t a

Represent function application

In Haskell the function application is so fundamental the language designer decide to use the most simple syntax to represent function application: simple juxtaposition of the function and arguments is enough.

f x

This is a syntax sugar, the parenthesis is omitted, the full expression should be

(f x)

When a function has multiple arguments, the arguments are curried

f x y z

Again its a syntax sugar, the full expression is

(((f x) y) z)

This is called currying, each function has one argument, by returning a partial function which will accept the second argument and so on.

Prefix arithmetic operator, the common arithmetic operator can be written as prefix notation, by surrounding the operator with parenthesis, the + becomes (+), cons : becomes (:)

let a = (+) 3 3
-- ((+) 3 3)
-- (((+) 3) 3)
let a = (:) 3 []
let a = (:) 4 ((:) 3 [])

Actually the infix notation is just syntax sugar, to make it looks more natural, but I think any sufficiently qualified programmer should have no problem with prefix notation. Its no reason to think which notation is better.

We can define our own operator function like this

let (^&) (x:xs) = x
let a = (^&) [1,2,3]
let (@#) a b =  a + b
let a = 3 @# 4
let a = (@#)  3 4

In Haskell its called infix operator, by wrap it with parenthesis , we convert it into prefix notation. Just like normal function .

Represent patterns

To match a tuple, you can write the pattern as a tuple

firstElementOfTuple (a,b,c) = a
*Main> let a = firstElementOfTuple ("hello", 3,4)
*Main> a

To match algebraic data type and extract the value from the type, we can use the parenthesis just like the way we construct the value by calling data constructor of the type.

data MyTypeFoo = MyTypeFoo Int
extractValue (MyTypeFoo a ) = a
*Main> let a = MyTypeFoo 4
*Main> :t a
a :: MyTypeFoo
*Main> extractValue a 

Here, the constructor is special function in pattern matching, the normal function can not be used this way

functionFoo a = 3
functionBar (functionFoo a) = a
    Parse error in pattern: functionFoo

The pattern (MyTypeFoo a) means it will match a value that constructed by data constructor MyTypeFoo and the value will be bound to variable a. You can reference the value with a at the right hand side of the equation.

There are some special constructors in Haskell and also some syntax sugar to make them easy to use. For example the cons constructor (:)

first (x:xs) = x

If we write in regular form it will be

first ((:) x xs) = x