Wednesday, October 7, 2009

How Haskell Works

The most baffling programming language I ever learned was Haskell. It is famed as one of the only purely functional programming languages in use today. A hiring rep from Microsoft told me that it was his favorite language, which sparked my interest.

Basic Syntax

You can define a function called "divide" that takes two arguments, divides them, and returns the result.

divide a b = a / b

You invoke the function like this:

two_thirds = divide 2 3

No parens, no commas. Just spaces.

Furthermore, since this is a functional language, you can define functions by simply assigning them from other existing functions.

div = divide
two_thirds = div 2 3

This shouldn't be anything too profound since Python, even JavaScript, can do this.

Now let's make a function that inverts a number:

invert a = divide 1 a
one_half = invert 2

The Confusing Part

Unlike in Python (or any other language I've seen), you can define a function that supplies only some of the arguments to another function.

invert = divide 1
one_half = invert 2

But I thought "divide" took 2 arguments, you might say. It actually doesn't.

How Haskell Works

Every function in Haskell takes exactly 1 argument. To explain this, I'll use Python. Here's the Python equivalent of our divide function from above:

def divide(a):
return lambda b: a / b

Here's how to call our python divide function:

two_thirds = divide(2)(3)

The result of divide(2) is a function that takes 1 argument called b. When it gets b it divides 2/b and returns that. All functions in Haskell behave this way.

Some Examples

negate a = -a
divide a b = a / b

-- here's a list of numbers:
numbers = [1,2,5,10]

-- the map function takes a function and
-- applies it to each item of a list
negated_numbers = map negate numbers
-- produces: [-1,-2,-5,-10]

-- here's our invert function
invert = divide 1
inverted_numbers = map invert numbers
-- produces: [1, 0.5, 0.2, 0.1]
-- equivalently:
inverted_numbers = map (divide 1) numbers

-- more complex:
-- this function inverts a list of numbers
invert_list = map invert

inverted_numbers = invert_list numbers

Obviously, there's a lot more to Haskell than presented here, but hopefully this helps explain some of the semantics of Haskell I had trouble with when I learned it.

No comments: