# Homework 1

This homework is written in literate Haskell; you can download the raw source to fill in yourself. You’re welcome to submit literate Haskell yourself, or to start fresh in a new file, literate or not.

Please submit homeworks via the DCI submission page.

Let’s learn some Haskell! We’ll be going over some rudiments in class, and there’s excellent documentation online.

In most places where I’d like you to fill in a definition, I’ve used the convenient Haskell term `undefined`, which let’s you compile an incomplete program. (Running undefined parts of your program is an error, and your program will crash.)

Please leave the following line in. (If you take it out, the grader will reject your program.) We’ll talk more about Haskell’s module system later in the semester.

``module Hw01 where``

You can test this program by running `ghci` on it. If you edit your code, you can use the `:reload` command to load in your new definitions.

If your program has type errors, it won’t compile.

Problem 1: natural recursion

Please don’t use any Prelude functions to implement these—just write natural recursion, like we did in class.

Write a function called `sumUp` that sums a list of numbers.

``````sumUp :: [Int] -> Int
sumUp []     = undefined
sumUp (x:xs) = undefined``````

Write a function called `evens` that selects out the even numbers from a list. For example, `evens [1,2,3,4,5]` should yield `[2,4]`. You can use the library function `even`.

``````evens :: [Int] -> [Int]
evens []     = undefined
evens (x:xs) = undefined``````

Write a function called `incAll` that increments a list of numbers by one. You’ll have to fill in the arguments and write the cases yourself.

``````incAll :: [Int] -> [Int]
incAll = undefined``````

Now write a function called `incBy` that takes a number and increments a list of numbers by that number.

``````incBy :: Int -> [Int] -> [Int]
incBy = undefined``````

Write a function `append` that takes two lists and appends them. For example, `append [1,2] [3,4] == [1,2,3,4]`. (This function is called `(++)` in the standard library… but don’t use that to define your version!)

``````append :: [Int] -> [Int] -> [Int]
append = undefined``````

Problem 2: data types

Haskell (and functional programming in general) is centered around datatype definitions. Here’s a definition for a simple tree:

``data IntTree = Empty | Node IntTree Int IntTree deriving (Eq,Show)``

Write a function `isLeaf` that determines whether a given node is a leaf, i.e., both its children are `Empty`.

``````isLeaf :: IntTree -> Bool
isLeaf Empty = undefined
isLeaf (Node l x r) = undefined``````

Write a function `sumTree` that sums up all of the values in an `IntTree`.

``````sumTree :: IntTree -> Int
sumTree = undefined``````

Write a function `fringe` that yields the fringe of the tree from left to right, i.e., the list of values in the leaves of the tree, reading left to right.

For example, the fringe of `Node (Node Empty 1 (Node Empty 2 Empty)) 5 (Node (Node Empty 7 Empty) 10 Empty)` is `[2,7]`.

``````fringe :: IntTree -> [Int]
fringe = undefined``````

Problem 3: insertion sort

Write a function `insertionSort` that takes a list of `Int`s and produces one in sorted order. Use the insertion sort algorithm. You might want to write a helper function.

``````insertionSort :: [Int] -> [Int]
insertionSort = undefined``````

Problem 4: binary search trees

Write a function `isBST` to determine whether or not a given tree is a strict binary search tree, i.e., the tree is either empty, or it is node such that:

• all values in the left branch are less than the value of the node, and
• all values in the right branch are greater than the value of the node.

I’ve given you a helper function `maybeBounded` that checks whether a given `Int` is bounded. It uses the Haskell `Maybe` type, which is essentially defined as:

``data Maybe Int = Nothing | Just Int``

`Maybe` makes a type nullable. In Java, every non-primitive type is nullable—the `null` object can have any class. In Haskell, you must explicitly ask for nullability, and nullness and non-nullness are both explicit: `Nothing` is null, and the non-null `Just x` holds a value `x`. We’ll look at this more deeply in the next assignment, when we talk about datatypes.

``````maybeBounded :: Maybe Int -> Maybe Int -> Int -> Bool
maybeBounded Nothing Nothing x = True
maybeBounded Nothing (Just upper) x = x < upper
maybeBounded (Just lower) Nothing x = lower < x
maybeBounded (Just lower) (Just upper) x = lower < x && x < upper``````
``````isBST :: IntTree -> Bool
isBST = undefined``````

Write a function `insertBST` that performs BST insert. You may assume your input is a BST.

``````insertBST :: Int -> IntTree -> IntTree
insertBST = undefined``````

Write a function `deleteBST` that removes a given value from a BST. You may assume your input is a BST. Feel free to look up the algorithm… I had to!

It doesn’t really matter which algorithm you use, so long as the function works correctly, i.e., for all BSTs `t`:

• `deleteBST x t` is a BST,
• `x` doesn’t appear in `deleteBST x t`,
• for all `y` in `t`, if `y /= x`, then `y` appears in `deleteBST y t`.

You are, as always, free to introduce any helper functions you might need.

``````deleteBST :: Int -> IntTree -> IntTree
deleteBST = undefined``````