Haskell Practice Questions

Most of the following questions have more than one good answer, so the given solution is not necessarily the only solution, or even the best.

  1. Write a function called isdigit that tests if a character is one of the digits '0', '1', …, '9'. It has this signature:

    isdigit :: Char -> Bool
    

    Solution:

    isdigit :: Char -> Bool
    isdigit c = elem c "0123456789"
    
  2. Write a function called isletter that tests if a character if one of the 26 lowercase letters 'a', 'b', …, 'z', or one of the 26 uppercase letters 'A', 'B', …, 'Z'. It has this signature:

    isletter :: Char -> Bool
    

    Solution:

    isalpha :: Char -> Bool
    isalpha c = elem c "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
    
  3. The following functions each take predicate function and a list as input, and remove certain items from the list based on the predicate function. They each have this signature:

    (a -> Bool) -> [a] -> [a]
    
    1. ltrim removes all items from the start of the list that satisfy the predicate function.
    2. rtrim removes all items from the end of the list that satisfy the predicate function.
    3. trim removes all items from both the start and end of the list that satisfy the predicate function.

    Solution:

    -- remove all occurrences of values at the start of a list that satisfy the
    -- given predicate function
    ltrim :: (a -> Bool) -> [a] -> [a]
    ltrim _ [] = []
    ltrim f (x:xs) = if f x then
                        ltrim f xs
                     else
                        x:xs
    
    -- remove all occurrences of values at the end of a list that satisfy the
    -- given predicate function
    rtrim :: (a -> Bool) -> [a] -> [a]
    rtrim f lst = reverse (ltrim f (reverse lst))
    
    -- remove all occurrences of values at the start/end of a list that satisfy the
    -- given predicate function
    trim :: (a -> Bool) -> [a] -> [a]
    trim f lst = ltrim f (rtrim f lst)
    
  4. Write the following two functions:

    1. lpad c n lst returns a new list equal to lst but with n copies of c on the left side. Write the most general type signature for it.

      For example:

      > lpad '*' 5 "apple"
      "*****apple"
      
    2. rpad c n lst returns a new list equal to lst but with n copies of c on the right side. Write the most general type signature for it.

      For example:

      > lpad '*' 5 "apple"
      "apple*****"
      

    Solution:

    lpad :: a -> Int -> [a] -> [a]
    lpad c n lst = (replicate n c) ++ lst
    
    rpad :: a -> Int -> [a] -> [a]
    rpad c n lst = lst ++ (replicate n c)