DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Roger has posted 34 posts at DZone. View Full User Profile

Real World Haskell Exercise - Ch 4, Ex 2-4

03.11.2010
| 1444 views |
  • submit to reddit
        // I'm posting the rest of these, mostly because I'm still patting myself on the back
// for my point-free implementation of exercise 3, and because I give myself about 
// two months before I entirely forget how I did it...


import Data.Char (digitToInt) -- we'll need ord
import Data.List (foldl')

                          

                          
{- Ex 2: The asInt_fold function uses error, so its 
         callers cannot handle errors. Rewrite it to 
         fix this problem.
-}
type ErrorMessage = String
asInt_either :: String -> Either ErrorMessage Int
asInt_either []  = Left "String is empty"
asInt_either "-" = Left "dash is not a number"
asInt_either ('-':xs) = Right $ (-1) * asInt_fold xs 
asInt_either str = Right $ asInt_fold str

{- Ex 3: The Prelude function concat 
         concatenates a list of lists into a single list, 
         and has the following type.

        concat :: [[a]] -> [a]
        
        Write your own definition of concat using foldr.
-}

list1 = [1,2,3,4,5]
list2 = [6,7,8,9,10]
list3 = [11,12,13,14,15]
list4 = [16,17,18,19,20]
listA = [list1, list2, list3, list4]

-- this was easy...
concat_foldr :: [[a]] -> [a]
concat_foldr = foldr (++) []

{- Ex 4: Write your own definition of the standard takeWhile 
         function, first using explicit recursion, then foldr.
         
         (I assume 2 separate functions...)
          
          --- test cases (from the Prelude comments)
          takeWhile (< 3) [1,2,3,4,1,2,3,4] == [1,2]
          takeWhile (< 9) [1,2,3] == [1,2,3]
          takeWhile (< 0) [1,2,3] == []

-}

takeWhile_rec :: (a -> Bool) -> [a] -> [a]
takeWhile_rec _ []          =  []
takeWhile_rec p (x:xs)
                | p x       = x : takeWhile_rec p xs
                | otherwise = []
                
takeWhile_foldr :: (a -> Bool) -> [a] -> [a]
takeWhile_foldr p = foldr (\x xs -> if p x then x:xs else []) []

dropWhile_foldr :: (a -> Bool) -> [a] -> [a]
dropWhile_foldr p = foldr (\x xs -> if p x then xs else x:xs) []