Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Personally, I believe Haskell syntax is a work of art. Learning how it fits together with currying is extremely satisfying. Also, the meaning of all the operators you mention, with the exception of (>>=), is immediately clear from their types.

    (.) :: (b -> c) -> (a -> b) -> (a -> c)
It is clear that it takes two functions, and chains them together to create a new function

    f . g = \x -> f (g x)
So

    double (addOne 3)
is equivalent to

    (double . addOne) 3
Similarly, (!!) has type

    (!!) :: [a] -> Int -> a
It is immediately obvious from the type that it acceses the object at a particular index in a list, so

   ['a', 'b', 'c'] !! 1 == 'b'
Also, the syntax complements currying extremely well

    f g h x
is equivalent to

   (((f g) h) x)

This allows for some very neat things.

   addOne :: Int -> Int 
   -- addOne 3 == 4

   map :: (a -> b) -> ([a] -> [b]) -- which is equivalent to '(a -> b) -> [a] -> [b]'
map is an extremely neat function, and is used in many languages. It applies a function to every element of a list, producing a new list.

Now, there are two ways to use map

    map addOne [1, 2, 3, 4] == [2, 3, 4, 5]
However, the above is equivalent to

   (map addOne) [1, 2, 3, 4]
From this we see there is another way to use map

   addOneList :: [Int] -> [Int]
   addOneList = map addOne

   -- addOneList [1, 2, 3, 4] = [2, 3, 4, 5]

Note how map was partially applied. In Haskell, map can be seen as doing two things. One is taking a function and a list, and applying the function to every element in it to produce a new list. However, you can also see map as a function transformer, taking an ordinary function, and converting it into a function that works on lists!

   map :: (a -> b) -> ([a] -> [b]) -- which is equivalent to '(a -> b) -> [a] -> [b]'


The Haskell's record/struct syntax is probably the worst of any language.

C style:

    a.b.c = 1;
Haskell:

    let b' = b a
        c' = 1 + c b'
        b'' = b' { c = c' }
    in c' { b = b'' }


It is bad, but couldn't you also write:

    a { b { c = 1 } }


It's (b . c .~ 1) with lens. Or a { b = (b a) { c = 1 } } without.


lens attempts to solve that. Though it does so at the cost of unreadable types.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: