-- CSCE 314 [Section 503] Programming Languages Spring 2021 -- Homework Assignment 2 (Total 70 points) -- Problem 1 (5 points) -- Student Name: Adam Taha -- UIN: 428007900 -- (IMPORTANT: Acknowledge any help received here) -- On my honor, as an Aggie, I have neither given nor received any unauthorized -- aid on any portion of the academic work included in this assignment. module Main where import Test.HUnit import System.Exit import Data.List import Data.Char -- *** Read Chapter 7 *** -- Problem 2 (15 points) -- Problem 2.1 (10 points) mergeBy :: (a -> a -> Bool) -> [a] -> [a] -> [a] mergeBy p [] [] = [] mergeBy p xs [] = xs mergeBy p [] ys = ys mergeBy p (x:xs) (y:ys) = if p x y then x : mergeBy p xs (y:ys) else y : mergeBy p (x:xs) ys -- Problem 2.2 (5 points) halve :: [a] -> ([a], [a]) halve (x:xs) = splitAt ((length (x:xs)) `div` 2) (x:xs) msortBy :: (a -> a -> Bool) -> [a] -> [a] msortBy p [] = [] msortBy p [x] = [x] msortBy p (x:xs) = mergeBy p (msortBy p half1) (msortBy p half2) where (half1, half2) = halve (x:xs) -- Problem 3 (15 points) -- Problem 3.1 (10 points) altMap altMap :: (a -> b) -> (a -> b) -> [a] -> [b] altMap f g [] = [] altMap f g (x:[]) = f x : [] altMap f g (x:y:xs) = f x : g y : altMap f g xs {- Problem 3.2 (5 points) Explain how your altMap works when it is applied as below. > altMap (*2) (`div` 2) [0..6] When applied as above, the altMap function will take in (*2) as the argument function f, (`div` 2) as the argument function g, and the list [0..6] as the argument list (x:y:xs) where each x represents the odd elements and y represents the even elements in the list, and xs represents the rest of the list. Each time the function is appliec the will go through each case and check whether the function has an empty list, or if the list only has one element left, or if there is a list with more than one element. Since neither of the first two cases can be applied when the function is first used the function then goes to the recursive case. When the function is executed the function will first apply *2 to the first element of the list, 0 which will return 0 for that element since 0*2 is 0, and then apply `div` 2 to the second element 1, which will return 0 since in integer division 1 divided by 2 is 0. The function will append f x and g x to the rest of the list being applied with altMap recursively. In the next use of altMap, the thrid element 2 becomes 4, and the fourth element 3 becomes 1. Next the fifth element 4 becomes 8, the sixth element 5 becomes 2. On this last application, the function checks to see if there is one element left and then the function will go through the last case by applying the (*2) to the last element 6 which results in 12. Then the number 12 is appended to an empty list signifying the end of his list. Therefore, the final result will be [0,0,4,1,8,2,12]. -} -- Problem 4 (10 points) concatenateAndUpcaseOddLengthStrings :: [String] -> String concatenateAndUpcaseOddLengthStrings = map toUpper . concat . filter (odd . length) -- Problem 5 (25 points) -- Problem 5.1 (10 points) myInsert :: Ord a => a -> [a] -> [a] myInsert x [] = [x] myInsert x (y:ys) = if x <= y then x : y : ys else y : myInsert x ys -- Problem 5.2 (5 points) mySort :: Ord a => [a] -> [a] mySort (x:xs) = foldr (\x xs -> myInsert x xs) [] (x:xs) {- Problem 5.3 (10 points) Explain how your mySort works when it is applied as below. Your explanation should be closely related to how foldr works. > mySort [3,1,4,2,5] When applied mySort will take in the list, and apply the operation (\x xs -> myInsert x xs) to the list [3,1,4,2,5] in which the base case is the empty list []. The operation (\x xs -> myInsert x xs) takes in an element to insert x and a list xs and returns the result of the function myInsert x xs. When applied the function will do the following: foldr (\x xs -> myInsert x xs) [] [3,1,4,2,5] foldr (\x xs -> myInsert x xs) [] 3:(1:(4:(2):(5:[]))) -The lambda expression operation will be applied with each element in the list. Each (:) is replaced by a (\x xs -> myInsert x xs) 3 (\x xs -> myInsert x xs) (1 (\x xs -> myInsert x xs) (4 (\x xs -> myInsert x xs) (2) (\x xs -> myInsert x xs) (5 (\x xs -> myInsert x xs) []))) -The expression will take in 5 as x and [] as xs, and apply myInsert 5 [] which will follow the first case and return [5]. 3 (\x xs -> myInsert x xs) (1 (\x xs -> myInsert x xs) (4 (\x xs -> myInsert x xs) (2) (\x xs -> myInsert x xs) [5])) -The expression will take in 2 as x and [5] as xs, and apply myInsert 2 [5] which will follow the second case and return [2,5] since 2 is <= 5 3 (\x xs -> myInsert x xs) (1 (\x xs -> myInsert x xs) (4 (\x xs -> myInsert x xs) [2,5]) -The expression will take in 4 as x and [2,5] as xs, and apply myInsert 4 [2,5] which will follow the second case and return [2,4,5] since 4 is <= 5 but not <= 2 3 (\x xs -> myInsert x xs) (1 (\x xs -> myInsert x xs) [2,4,5]) -The expression will take in 1 as x and [2,4,5] as xs, and apply myInsert 1 [2,4,5] which will follow the second case and return [1,2,4,5] since 1 is <= 2. 3 (\x xs -> myInsert x xs) [1,2,4,5] -The expression will take in 3 as x and [1,2,4,5] as xs, and apply myInsert 3 [1,2,4,5] which will follow the second case and return [1,2,3,4,5] since the first element 3 is less than is 4 This final ouput is the sorted list [1,2,3,4,5] -} myTestList = let te s e a = test $ assertEqual s e a tb s b = test $ assertBool s b in TestList [ te "mergeBy 1" "GFEDBA" (mergeBy (>) "FED" "GBA") , te "mergeBy 2" "HMaouiwdy" (mergeBy (<) "Howdy" "Maui") , te "msortBy 1" " 'eggim" (msortBy (<) "gig 'em") , te "msortBy 2" "nmlkieecbbaJ " (msortBy (>) "Jack be nimble") , te "msortBy 3" "" (msortBy (<) "") , te "altMap 1" [10,200,30,400,50] (altMap (* 10) (* 100) [1,2,3,4,5]) , te "altMap 2" False (and (altMap even odd [1..10])) , te "altMap 3" "hAsKeLl iS FuN!" (altMap toLower toUpper "Haskell IS fun!") , te "concatenateAndUpcaseOddLengthStrings" "HERE'S AN EXAMPLE" (concatenateAndUpcaseOddLengthStrings ["here's ", "an ", "a ", "example"]) , te "myInsert 1" "How are you?" (myInsert 'o' "Hw are you?") , te "myInsert 2" "abcdefg" (myInsert 'c' "abdefg") , te "mySort" " Jabcceikkqu" (mySort "Jack be quick") ] main = do c <- runTestTT myTestList putStrLn $ show c let errs = errors c fails = failures c exitWith (codeGet errs fails) codeGet errs fails | fails > 0 = ExitFailure 2 | errs > 0 = ExitFailure 1 | otherwise = ExitSuccess
Write, Run & Share Haskell code online using OneCompiler's Haskell online compiler for free. It's one of the robust, feature-rich online compilers for Haskell language, running the latest Haskell version 8.6. Getting started with the OneCompiler's Haskell editor is easy and fast. The editor shows sample boilerplate code when you choose language as Haskell and start coding.
OneCompiler's Haskell online editor supports stdin and users can give inputs to programs using the STDIN textbox under the I/O tab. Following is a sample Haskell program which takes name as input and prints hello message with your name.
main = do
name <- getLine
putStrLn ("Hello " ++ name ++ ", Happy learning!")
Haskell is purely a functional programming language which was introduced in 1990's.
Data-type | Description |
---|---|
Numbers | Haskell is intelligent to identify numbers without specifying data type |
Characters | Haskell is intelligent to identify characters and strings without specifying data type |
Tuple | To declare multiple values in a single data type. Tuples are represented in single paranthesis. For example (10, 20, 'apple') |
Boolean | To represent boolean values, true or false |
List | To declare same type of values in a single data type. Lists are represented in square braces.For example [1, 2, 3] or `['a','b','c','d'] |
When ever you want to perform a set of operations based on a condition or set of conditions, then If-Else/ Nested-If-Else are used.
main = do
let age = 21
if age > 18
then putStrLn "Adult"
else putStrLn "child"
Function is a sub-routine which contains set of statements. Usually functions are written when multiple calls are required to same set of statements which increases re-usuability and modularity. Functions play an important role in Haskell, since it is a purely functional language.
multiply :: Integer -> Integer -> Integer --declaration of a function
multiply x1 x2 = x1 * x2 --definition of a function
main = do
putStrLn "Multiplication value is:"
print(multiply 10 5) --calling a function