Workshop 03

Embed Size (px)

Citation preview

  • 7/30/2019 Workshop 03

    1/5

    Declarative Programming

    Answers to workshop exercises set 3.

    QUESTION 1Write a Haskell version of the classic quicksort algorithm for lists.(Note that while quicksort is a good algorithm for sorting arrays, it is notactually that good an algorithm for sorting lists; variations of merge sortgenerally perform better. However, that fact has no bearing on this exercise.)

    ANSWERHere is one version of this function:

    >qsort1 :: (Ord a) => [a] -> [a]>qsort1 [] = []>qsort1 (pivot:xs) = qsort1 lesser ++ [pivot] ++ qsort1 greater> where> lesser = filter (< pivot) xs> greater = filter (>= pivot) xs

    QUESTION 2Given the following type definition for binary search trees from lectures,

    >data Tree k v = Leaf | Node k v (Tree k v) (Tree k v)

    > deriving (Eq, Show)

    define a function

    >same_shape :: Tree a b -> Tree c d -> Bool

    which returns True if the two trees have the same shape: same arrangementof nodes and leaves, but possibly different keys and values in the nodes.

    ANSWER

    >same_shape Leaf Leaf = True>same_shape Leaf (Node _ _ _ _) = False

    >same_shape (Node _ _ _ _) Leaf = False>same_shape (Node _ _ l1 r1) (Node _ _ l2 r2)> = same_shape l1 l2 && same_shape r1 r2

    QUESTION 3Consider the following type definitions, which allow us to representexpressions containing integers, variables "a" and "b", and operatorsfor addition, subtraction, multiplication and division.

    >data Expression> = Var Variable> | Num Integer> | Plus Expression Expression

    > | Minus Expression Expression> | Times Expression Expression> | Div Expression Expression

    >data Variable = A | B

    For example, we can define exp1 to be a representation of 2*a + bas follows:

    >exp1 = Plus (Times (Num 2) (Var A)) (Var B)

  • 7/30/2019 Workshop 03

    2/5

    Write a function eval :: Integer -> Integer -> Expression -> Integerwhich takes the values of a and b and an expression, and returns thevalue of the expression. For example eval 3 4 exp1 = 10.

    ANSWER

    >eval a b (Var A) = a>eval a b (Var B) = b>eval a b (Num n) = n>eval a b (Plus e1 e2) = (eval a b e1) + (eval a b e2)>eval a b (Minus e1 e2) = (eval a b e1) - (eval a b e2)>eval a b (Times e1 e2) = (eval a b e1) * (eval a b e2)>eval a b (Div e1 e2) = (eval a b e1) `div` (eval a b e2)

    QUESTION 4Consider the following type definitions (from lectures) which allow usto represent Boolean and integer expressions.

    >data BoolExpr> = BoolConst Bool> | BoolOp BoolOp BoolExpr BoolExpr> | CompOp CompOp IntExpr IntExpr>data IntExpr

    > = IntConst Int> | IntOp IntOp IntExpr IntExpr> | IntIfThenElse BoolExpr IntExpr IntExpr

    Here we give just a few operators.

    >data BoolOp = BoolAnd | BoolOr>data IntOp = IntPlus | IntMinus | IntTimes | IntDiv>data CompOp = CompLess | CompGreater | CompEqual

    For example, we can define exp2 to be a representation of the expressionif 1+1 > 2 then 3 else 4

    as follows:

    >exp2 => IntIfThenElse> (CompOp CompGreater> (IntOp IntPlus (IntConst 1) (IntConst 1))> (IntConst 2))> (IntConst 3)> (IntConst 4)

    Define a function ints_in :: IntExpr -> [Int] which returns the list ofinteger constants in the expression, in the order they occur (duplicatesshould not be removed). For example, ints_in exp2 = [1,1,2,3,4].

    ANSWERDue to the mutual recursion in the types we use two mutually recursivefunctions. ints_in_bool returns the list of Ints in a BoolExpr.

    >ints_in :: IntExpr -> [Int]>ints_in (IntConst x) = [x]>ints_in (IntOp _ x y) = ints_in x ++ ints_in y>ints_in (IntIfThenElse b x y) => ints_in_bool b ++ ints_in x ++ ints_in y

  • 7/30/2019 Workshop 03

    3/5

  • 7/30/2019 Workshop 03

    4/5

    point 2

    Assume the existence of the function font_tag_to_str :: Font_tag -> String.

    ANSWER

    >html_to_str :: HTML -> String>html_to_str [] = "">html_to_str (x:xs) => html_element_to_str x ++ html_to_str xs

    >html_element_to_str :: HTML_element -> String>html_element_to_str (HTML_text s) = s>html_element_to_str (HTML_font ft x) => "" ++> (html_to_str x) ++ "">html_element_to_str (HTML_p x) => "\n

    " ++ (html_to_str x) ++ "\n

    ">html_element_to_str (HTML_ul xs)> = "\n" ++ (html_list_to_str xs) ++ "\n\n">html_element_to_str (HTML_ol xs)> = "\n" ++ (html_list_to_str xs) ++ "\n\n"

    >html_list_to_str :: [HTML] -> String>html_list_to_str [] = "">html_list_to_str (x:xs) => "\n\n" ++ (html_to_str x) ++ html_list_to_str xs

    We provide a stub for font_tag_to_str so that the above code can be tested:

    >font_tag_to_str _ = ""

    Simple test:

    >test1 = do putStr (html_to_str doc1)

    QUESTION 7If you are working on a program that functioned as a web server, and thusits output was in the form of web pages, you can

    (a) have the program write out each part of the page as soon as it has decidedwhat it should be;

    (b) have the program generate the output in the form of a string, and thenprint the string;

    (c) have the program generate the output in the form of a representationsuch as the HTML type of the previous questions, and then convert thatto a string and then print the string.

    Which of these approaches would you choose, and why?

    ANSWERThe best choice for nearly all non-trivial applications will be (c).

    There are several reasons for structuring data. One you are probablyfamiliar with is so more efficient algorithms can be used (e.g. usingtrees to allow O(log N) search and update). Another is to incorporatemore meaning (and to eliminate things which have no meaning). For example,the HTML data type can only represent correct HTML. Strings, on theother hand, can contain arbitrary character sequences, most of which are not

  • 7/30/2019 Workshop 03

    5/5

    valid HTML. A function which returns the HTML data type is not GUARANTEEDto be correct, but there are a whole class of bugs it cannot exhibitthat functions that generate strings or do I/O directly CAN exhibit.The data type also leads to a natural way of structuring the code,which helps with correctness.

    QUESTION 8This type is an alternative way to represent HTML documents (the added primesare to avoid name clashes):

    >data HTML'> = HTML_seq' [HTML]> | HTML_text' String> | HTML_font' Font_tag HTML> | HTML_p' HTML> | HTML_ul' [HTML]> | HTML_ol' [HTML]

    If you were working on a program that manipulated representations of HTMLdocuments, would you choose this representation over the previous one?Why or why not?

    ANSWERIt is very rare that one representation is always better than another;

    which one is better generally depends on exactly what you will be doingwith the representation. One advantage of this representation is thatit is slightly simpler than the previous one, and hence the code using itwill typically be simpler. Most operations on it will require two functions,one for HTML and the other for [HTML] (and there may be convenient higher orderfunctions already defined which are helpful for [HTML]), rather than three(one for HTML, one for HTML_element and one for [HTML]) as with the previousversion. A potential disadvantage is that there are more ways to representthe same data, since you can have a single element list inside HTML_seq.It is sometimes helpful to have only a single representation for a valuewhen you are generating such representations, particularly when you arecomparing them.