words with fold

Monday, January 26th, 2009

Real World Haskell, Exercise 10, p. 98: Write the words function using list folds:

myWords :: String -> [String]
myWords s = reverse (foldr step [] (trim s))

step :: Char -> [String] -> [String]
step c [] = [c:[]]
step c acc 
    | (isSpace c) = acc ++ [""]
    | otherwise = (take ((length acc) - 1) acc) ++ [c:(last acc)]

isSpace :: Char -> Bool
isSpace ' '  = True
isSpace '\n' = True
isSpace '\r' = True
isSpace '\t' = True
isSpace _    = False

lstrip :: String -> String
lstrip [] = ""
lstrip (x:xs) 
  | (isSpace x) = lstrip xs
  | otherwise = x:xs

rstrip :: String -> String
rstrip s = reverse (lstrip (reverse s))

trim :: String -> String
trim = lstrip . rstrip

Moral of this exercise: you can only pass a list to ++. You can’t use ++ to append a Char to a String. You have to append [c] instead.
(more…)

My Subcategories Vanished

Monday, January 26th, 2009

OK. This is weird. WordPress has lost all my subcategories. E.g. I can assign a post to Software Development but not Software Development/Haskell. OK, I seem to have gotten them back by clicking “Add New Category.” Probably some strange AJAX bug.

Hypothesis: cycles cannot be implemented only with folds

Saturday, January 24th, 2009

The cycle function turns a list into an infinite list by repeating it. For instance, cycle [1,2,3] is [1,2,3,1,2,3,1,2,3...]. I could be wrong but I don’t think you can do this one purely with folds and here’s why:
(more…)

any with foldr

Friday, January 23rd, 2009
myAny :: (a -> Bool) -> [a] -> Bool
myAny f [] = False
myAny f (x:xs) = foldr step False xs
     where step x acc = acc || f x 

I’m beginning to hate type inference. Yes the compiler can figure out the types, but the human (i.e. me) often can’t without running the compiler. Redundancy and verbosity are not bugs. They are features. Human language (e.g. English) is verbose and redundant for good reason. Redundancy helps humans understand.

The source code is not just for the compiler. Otherwise we’d write in machine language. User interface factors need to be considered in the design of programming languages.

foldr Starts at the Head

Wednesday, January 21st, 2009

It took me long enough to realize that foldr still moves from the beginning to the end of a list. Somehow I thought it started at the right (i.e. the tail) of the list. Once I realized that Exercise 7 was easy:

Write your own definition of the standard takeWhile function, first using explicit recursion, and then foldr.

(more…)

Android Notebook, page 4

Wednesday, January 21st, 2009

Probably not a coincidence, but all this lifecycle stuff reminds me of applets, albeit with somewhat more complicated argument lists and fancier names. There are certain patterns that show up again and again. Event listeners are one. Event loops are another. And life cycle methods are a third. Sometimes the trick to learning a new system is recognizing the old patterns in new language. Of course, this can trip you up badly when the pattern is something truly new, and when you try to fit it into old mental models. You can also get tripped up by assuming that certain contingent details are the same in the new instantiation of the pattern as in the old one.


The tab key doesn’t work like you’d expect–it doesn’t advance from one field to the next. I’m not sure if this is a limitation of the framework or just the sample app. This is completely irrelevant on a phone, but may become important if third parties start using the Android platform as a base for netbooks.


Too much copy and paste , and not enough thinking in the tutorial. I should try to work backwards from the sample app on the screen to understand where the different fields are coming from. Let’s see there are:
(more…)