Playing with sections in Haskell

Consider the function (:) in Haskell…

Hugs> :t (:)
(:) :: a -> [a] -> [a]

So, (:) is a polymorphic function which takes an element of some type, and a list of elements of that type, and returns a list of elements of that type. In particular, it prepends the singleton element onto the list. For example:

Hugs> 'c' : "ello"

Now for the fun part.

Hugs> :t ('c':)
('c' :) :: [Char] -> [Char]

Here, we see that ('c':) is a function which takes a list of characters (ie a string) and returns another one. As you might expect, it prepends it with a 'c':

Hugs> ('c':) "ello"

('c':) is an example of a section: we “partially evaluate” a function by providing only some of its parameters, which yields a new function. Obviously this is only possible if we have higher-order functions in our language.

We can take the section “on the other side” of the :, and define the function which takes a character and prepends it onto the string "ello"

Hugs> (:"ello") 'c'

What’s its type?

Hugs> :t (:"ello")
flip (:) "ello" :: Char -> [Char]

Interesting. The type is as we would expect (Char -> [Char]), but what’s this flip thing?

Hugs> :t flip
flip :: (a -> b -> c) -> b -> a -> c

So flip takes a function with type signature (a -> b -> c) and returns an equivalent function with type signature (b -> a -> c) – OK, simple enough. But why did hugs introduce it here, I wonder, though, why didn’t hugs just do what ghci does, and say:

Prelude> :t (:"ello")
(:"ello") :: Char -> [Char]

? I say: shrug.

In other news, I’ve just discovered Neil Mitchell’s Haskell blog. I met Neil at BCTCS 05 in Nottingham, and again at BCTCS 06 in Swansea (though at that time I felt like I was moving away from TCS). He’s a thoroughly nice bloke, and clearly knows considerably more about Haskell than I do, thus, a good blog to find. I enjoyed:

I think I was quite a bit less successful at explaining this one. The only way you can show sequence is not necessary is by writing an OS, a compiler, a web server etc in Haskell – all of which have been done. Unfortunately I only had a small piece of paper so couldn’t write any of those.

Neil Mitchell, “Describing Haskell to an Ada programmer”.

(The section saga continues here.

4 Responses to “Playing with sections in Haskell”

  1. Cale Gibbard
    April 15th, 2007 | 3:12 am

    Right sections like (* x) are generally desugared to flip (*) x, which explains the result that Hugs is giving you — it’s just done some of the desugaring before printing the expression it gives you, whereas ghci gives you back the expression in the form you originally typed it.

    I agree with you though that ghci’s policy of handing you things back in as close to their original form as possible seems like a good thing.

  2. Logan Capaldo
    April 15th, 2007 | 2:22 pm

    I disagree, and contend that hugs has the correct behavior. Without hugs desugaring it you wouldn’t have ha a chance to ask a question and find out what flip was :)

  3. April 15th, 2007 | 11:27 pm

    A short comment about wording. You say that using sections is to “partially evaluate” a function. Well, there is no evaluation going on here so I think that’s a bit misleading. What we’re really doing is partially *applying* the function.

  4. April 16th, 2007 | 10:43 am

    Thanks, Josef. Yeah, as I wrote it I had a tickly feeling I was skating on thin ice, correctness-wise. Thanks for the correction!