The Devil is in the Details

This story happened a while ago, but because I've been so busy I haven't really had the time to put it on (electronic) paper. While hanging out on Twitter I saw a message asking why one version of Haskell code was preferred over another. So I followed the link and saw the code below (sorry for the formatting issues. Geshi isn't very good with http links):

1) From

  1. take' :: (Num i, Ord i) => i -> [a] -> [a]
  2. take' n _
  3. | n <= 0 = []
  4. take' _ [] = []
  5. take' n (x:xs) = x : take' (n-1) xs


2) Just playin

  1. take' :: (Num i, Ord i) => i -> [a] -> [a]
  2. take' 0 _ = []
  3. take' _ [] = []
  4. take' n (x:xs) = x : take' (n-1) xs

Freefromz, the author of the code, was trying to do some code reduction. And while his version does look a little nicer, the lack of error checking makes the function a little incomplete and problematic. I noticed this right away, but it took a little while to get the idea across over Twitter; it's a bit difficult to relay complex concepts in 140 characters or less. Ultimately it was the tweet I sent him that said, “@freeformz right. Let me ask you this question, in #2 what happens it I input -2 for n?” to which he replied, “@bryceverdier it fails. duh on me. ;-)” that turned the light on for him.

This was my first time troubleshooting someone else's Haskell code. I'm really grateful that it was an easy one, because if it was any more complicated it probably would have been too difficult for my current Haskell programming abilities--something I intend to work on improving now that I have purchased my own copy of Real World Haskell. YAY!


This is one example where I prefer Erlang's syntax:

  1. take(N, [H|T]) where N >= 0 -> [H|take(N-1, T)];
  2. take(_, _) -> [].

It's just that little bit more intuitive and removes the extra pattern match.

If you made it this far down into the article, hopefully you liked it enough to share it with your friends. Thanks if you do, I appreciate it.

Bookmark and Share