HASKELL
HASKELL
NAME:HASWANTH
ROLL NO:422238
SECTION:B
- **Char**: This type represents a single character, such as `'a'`. It is enclosed in single
quotes.
The expressions `"a"` and `'a'` do **not** represent the same value. The former is a
**String**, while the latter is a **Char**. In summary, they are different types and
represent different forms of character data.
SOLUTION:
We are also assuming `average` is a function that takes two integers and returns their
average.
`average :: Int -> Int -> Int`
`average x y = (x + y) `div` 2`
### Summary:
4. If you remove the optional type annotation from the above definition of square, what
type
will the compiler infer? You can find out by pressing -i in Haskell for Mac, while your
cursor is on the function name, or by typing :type square or :t square in GHCi.
If you remove the type annotation from the `square` function, the compiler will infer the
type as:
1. **`square_1`**: **Valid**
2. **`1square`**: **Invalid** (cannot start with a digit)
3. **`Square`**: **Valid** (but typically used for types)
4. **`square!`**: **Invalid** (exclamation mark not allowed)
5. **`square'`**: **Valid** (apostrophe is allowed)
### Summary:
- **Valid**: `square_1`, `Square`, `square'`
- **Invalid**: `1square`, `square!`
2. Define a new function showResult, that, for example, given the number 123, produces
a
string as follows:
showResult 123 "The result is 123"
Use the function show in the definition of the new function.
Code:
-- Function to show the result
showResult :: Show a => a -> String
showResult n = "The result is " ++ show n
Output:
main :: IO ()
main = putStrLn (showAreaOfCircle 12.3)
Output:
4. Write a function sort2 :: Ord a => a -> a -> (a, a) which accepts two Int
values as arguments and returns them as a sorted pair, so that sort2 5 3 is
equal to (3,5). How can you define the function using a conditional, how can
you do it using guards?
Code:
-- Define the sort2 function using min and max
sort2 :: Ord a => a -> a -> (a, a)
sort2 x y = (min x y, max x y)
Output:
5. Consider a function
which compares the values of two pairs. It returns True if both pairs contain
the same values, regardless of the order. For example, almostEqual (3,4)
(4,3) is True, but almostEqual (3,4) (3,5) is False. Which of the following
definitions return the correct value? Which of the definitions would you
consider good style? Why? (The operator (&&) is logical ”and”, the operator
(||) is logical ’or’, and (==) tests if two values are equal. The first two are of
type Bool -> Bool -> Bool; the third is of type Eq a => a -> a -> Bool.)
The question asks to evaluate and find the correct implementation of the function `almostEqual`,
which checks if two pairs of values are equal, regardless of the order of the values within the pairs.
There are several implementations provided in the images. Let's break down each version.
```haskell
almostEqual (x1, y1) (x2, y2)
| (x1 == x2) && (y1 == y2) = True
| (x1 == y2) && (y1 == x2) = True
| otherwise = False
```
- This definition checks if either the pairs `(x1, y1)` are equal to `(x2, y2)` in the same order or if they
are equal in reverse order.
- This function works correctly and is simple in its structure.
- **Correct behavior:** This function correctly identifies equal pairs regardless of order.
```haskell
almostEqual (x1, y1) (x2, y2)
| (x1 == x2) = (y1 == y2)
| (x1 == y2) = (y1 == x2)
| otherwise = False
```
- This version uses the guard to first check if `x1 == x2`, and if so, it checks if `y1 == y2`.
- Similarly, if `x1 == y2`, it checks if `y1 == x2`.
- This version works the same as the first, but it uses guards to express the same logic.
- **Correct behavior:** This implementation also works correctly and is clear.
### 3. **Third implementation (using a `swap` helper function):**
```haskell
almostEqual pair1 pair2
= (pair1 == pair2) || (swap pair1 == pair2)
where
swap (x, y) = (y, x)
```
- This implementation first checks if the two pairs are equal in the same order, and then it checks if
the `swap` of `pair1` (reversing it) is equal to `pair2`.
- The helper function `swap` flips the pair `(x, y)` to `(y, x)`.
- **Correct behavior:** This version is correct and concise, using a helper function to simplify the
comparison logic.
```haskell
almostEqual (x1, y1) (x2, y2)
= if (x1 == x2)
then
if (y1 == y2)
then True
else False
else
if (x1 == y2)
then
if (x2 == y1)
then True
else False
else False
```
### Conclusion:
All four implementations provide the correct result, but the best style would be either the first or
third implementation. Both of these are concise and clear. The third implementation, using a helper
function (`swap`), may be slightly better for readability because it abstracts the logic of reversing a
pair into a named function.
Thus, the **third implementation** with the `swap` helper function is a good balance of clarity and
functionality.
6. Define a function isLower :: Char -> Bool which returns True if a given character is a
lower case letter. You can use the fact that characters are ordered, and for all lower case
letters ch we have ʹaʹ ≤ ch and ch ≤ ʹzʹ. Alternatively, you can use the fact
that ['a'..'z'] evaluates to a list containing all lower case letters.
Code:
isLower :: Char -> Bool
isLower ch = ch `elem` ['a'..'z']
Output:
7. Write a function mangle :: String -> String which removes the first letter of a word and
attaches it at the end. If the string is empty, mangle should simply return an empty string:
mangle "Hello" "elloH"
mangle "I" "I"
mangle "" ""
CODE:
mangle :: String -> String
mangle "" = "" -- Return empty string if input is empty
mangle [x] = [x] -- If the string has only one character, return the same string
mangle (x:xs) = xs ++ [x] -- Otherwise, move the first character to the end
Output:
8. Implement division on Int, divide :: Int -> Int -> Int using the list functions
described in this section. Hint: first, write a function that returns all the multiples of a
given number up to a specific limit.
divide 5 10 2
divide 5 8 1
divide 3 10 3
CODE:
-- Helper function to generate multiples up to a limit
multiplesUpTo :: Int -> Int -> [Int]
multiplesUpTo divisor limit = takeWhile (<= limit) [divisor, 2 * divisor ..]
10. What are the values of the following expressions and what is wrong with the ones that
give errors?
1:[2,3,4]
1:2:3:4:[]
[1,2,3]:[4..7]
[1,2,3] ++ [4..7]
1:['a','b']
"abc"++"cd"
"a":"bCc"
"a" ++ "bCc"
'a':'b'
'a':"b"
[1,4,7] ++ 4:[5:[]]
[True,True:[]]
True:[True,False]
OUTPUT:
Let's break down each expression to understand what works, what errors occur, and why.
### 1. `1:[2,3,4]`
- **Type**: `[Int]` (list of integers)
- **Value**: `[1, 2, 3, 4]`
- **Explanation**: This expression is valid. The number `1` is prepended to the list `[2, 3, 4]`, resulting
in `[1, 2, 3, 4]`.
### 2. `1:2:3:4:[]`
- **Type**: `[Int]` (list of integers)
- **Value**: `[1, 2, 3, 4]`
- **Explanation**: This is another valid list construction using the `(:)` (cons) operator. It's equivalent
to writing `[1, 2, 3, 4]` explicitly.
### 3. `[1,2,3]:[4..7]`
- **Error**: **Type mismatch**
- **Explanation**: This gives an error because `:` is the cons operator, which adds a single element to
a list. However, in this case, you are trying to add a list `[1,2,3]` to another list `[4..7]`, which is not
allowed. You need to concatenate the lists using `++` instead of `:`.
### 5. `1:['a','b']`
- **Error**: **Type mismatch**
- **Explanation**: This gives an error because you're trying to combine an integer (`1`) with a list of
characters (`['a','b']`). Lists must contain elements of the same type, so this is not allowed.
### 7. `"a":"bCc"`
- **Error**: **Type mismatch**
- **Explanation**: This gives an error because the `(:)` operator is used to prepend an element to a
list. However, `"a"` is a string (which is a list of characters) and not a single character. To prepend a
single character, you would need something like `'a' : "bCc"`.
### 9. `'a':'b'`
- **Error**: **Type mismatch**
- **Explanation**: This gives an error because `'b'` is a character, and you are trying to prepend `'a'`
to it using the `(:)` operator, which requires the second operand to be a list (not a single character).
You might have meant to write `'a' : "b"` (which is valid).
---
11. Write a recursive function fact to compute the factorial of a given positive number
(ignore the case of 0 for this exercise).
fact n = 1 * 2 * ... * n
Why is the function fact a partial function? Add an appropriate error case to the function
definition.
The factorial of a positive number nnn, denoted as n!n!n!, is the product of all
integers from 1 to nnn. Factorials are typically defined for non-negative integers, but
in this case, we're focusing on positive integers (ignoring 0).
CODE:
Factorial Function (Without Error Case):
fact :: (Eq a, Num a) => a -> a
fact 1 = 1
fact n = n * fact (n - 1)
CODE:
fact :: (Eq a, Num a, Ord a) => a -> a
fact n
| n < 1 = error "Factorial is not defined for non-positive numbers!"
| n == 1 = 1
| otherwise = n * fact (n - 1)
OUTPUT:
12. In the previous chapter, we introduced the ellipsis list notation in Haskell, which allows us
to write
[m..n]
as shorthand for the list
[m, m+1, m+2, ..., n]
for numbers m and n, with n greater or equal m. Write
a recursive function enumFromTo which produces such a list given m and n, such that
enumFromTo m n = [m..n]
As enumFromTo is a Prelude function, you have to add the line
import Prelude hiding (enumFromTo)
to your program.
CODE:
-- Importing Prelude but hiding the built-in enumFromTo function
import Prelude hiding (enumFromTo)
13. Write a recursive function countOdds which calculates the number of odd elements in a
list of Int values:
countOdds [1, 6, 9, 14, 16, 22] = 2
Hint: You can use the Prelude function odd :: Int -> Bool, which tests whether a
number is odd.
CODE:
-- Recursive function to count odd elements in a list
countOdds :: [Int] -> Int
countOdds [] = 0 -- Base case: an empty list has 0 odd numbers
countOdds (x:xs)
| odd x = 1 + countOdds xs -- If x is odd, add 1 to the result
| otherwise = countOdds xs -- If x is even, continue with the rest of the list
OUTPUT:
14. Write a recursive function removeOdd that, given a list of integers, removes all odd
numbers from the list, e.g.,
removeOdd [1, 4, 5, 7, 10] = [4, 10]
CODE:
-- Recursive function to remove odd numbers from a list
removeOdd :: [Int] -> [Int]
removeOdd [] = [] -- Base case: an empty list remains empty
removeOdd (x:xs)
| odd x = removeOdd xs -- If x is odd, skip it and process the rest of the list
| otherwise = x : removeOdd xs -- If x is even, keep it and process the rest of the list
15. Challenge: At the end of the last screencast, demonstrating the implementation
of closestPoint :: Point -> [Point] -> Point, we mentioned that the final
implementation is less efficient than one might hope, as it uses the distance functions
twice —instead of once— per recursive step. Improve the implementation to avoid that
inefficiency.
CODE:
-- Define the type for Point
type Point = (Double, Double)
16. mplement a function colouredFTree :: Float -> Int -> Colour -> Line ->
Picture that elaborates on fractalTree by accepting the colour of the tree as an
additional argument.
17. Vary colouredFTree by using the fade function, which we discussed in the context of
spiral rays, to incrementally alter the colour in each recursive step.
18. Vary colouredFTree further by implementing and using factor as demonstrated in the
last screencast.
HASKELL LAB TASK 2
1. Implement a function halves that takes a list of integers and divides each element of
the list in two
CODE:
-- Function to divide each element of a list by 2
halves :: [Int] -> [Int]
halves xs = map (`div` 2) xs
OUTPUT:
2. Implement a function stack that takes the first element of a list and moves it to the
back
CODE:
stack :: [a] -> [a]
stack [] = []
stack (x:xs) = xs ++ [x]
OUTPUT:
4. Implement a function factors that takes an Int and returns a list off all its factors (i.e. all
the Int's bigger than 1 and less than that Int that are divisible without a remainder)
CODE:
factors :: Int -> [Int]
factors n = [x | x <- [2..(n-1)], n `mod` x == 0]
OUTPUT:
5. Implement a function pivot that takes a value and a list, then returns two lists in a tuple,
with the-- first list being all elements <= to the value, and the second list being all
elements >
the value-- I.e. pivot 3 [5,6,4,2,1,3]= ([2,1,3],[5,6,4])
CODE:
pivot :: Ord a => a -> [a] -> ([a], [a])
pivot value lst = (filter (<= value) lst, filter (> value) lst)
OUTPUT:
6. Implement the function treeHeight that returns the largest height of a Tree
7. -- E.x.
a
/\
bc
/\
de
has a height of 3 (elements d and e are both at "height" 3 in the tree) NOTE
the Empty Tree
is of height 0
CODE:
data Tree a = Empty | Node a (Tree a) (Tree a)
exampleHeight :: Int
exampleHeight = treeHeight exampleTree
OUTPUT:
8. Implement the function merge that takes two lists that (assuming both lists are already
sorted) merges them together in to a sorted list
CODE:
merge :: (Ord a) => [a] -> [a] -> [a]
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys)
| x <= y = x : merge xs (y:ys)
| otherwise = y : merge (x:xs) ys
main :: IO ()
main = do
let list1 = [1, 3, 5, 7]
let list2 = [2, 4, 6, 8]
let mergedList = merge list1 list2
print mergedList -- Output: [1,2,3,4,5,6,7,8]
OUTPUT:
9. Implement the function mergeSort that sorts a list by reclusively splitting a list, and
merging
the sorted lists back together. NOTE singleton and empty lists are already sorted
CODE:
merge :: (Ord a) => [a] -> [a] -> [a]
merge [] ys = ys
merge xs [] = xs
merge (x:xs) (y:ys)
| x <= y = x : merge xs (y:ys)
| otherwise = y : merge (x:xs) ys
mergeSort :: (Ord a) => [a] -> [a]
mergeSort [] = []
mergeSort [x] = [x]
mergeSort xs =
let mid = length xs `div` 2
left = take mid xs
right = drop mid xs
in merge (mergeSort left) (mergeSort right)
main :: IO ()
main = do
let unsortedList = [5, 2, 9, 1, 5, 6]
let sortedList = mergeSort unsortedList
print sortedList
OUTPUT:
10. Implement the function sortProp that tests if a list is sorted or not. NOTE you can use
this
with QuickCheck to test your mergSort function by calling quickCheck (sortProp .
mergeSort)
CODE:
sortProp :: Ord a => [a] -> Bool
sortProp [] = True
sortProp [_] = True
sortProp (x:y:xs) = x <= y && sortProp (y:xs)
OUTPUT:
11. Implement the function lookup that takes a list of tuples, where the first element of the
tuple serves as a key and the second element a value (a list like this is also known as a
dictionary), and a key value, then looks up the first occurring element corresponding to
that
key. The return value is wrapped in the Maybe type, so if the key doesn't occur
anywhere in
the list the function returns Nothing
E.x. lookup 2 [(0,'a'),(1,'b')] == Nothing
lookup 2 [(0,'a'),(2,'b'),(2,'c')] == Just 'b'
CODE:
myLookup :: Eq a => a -> [(a, b)] -> Maybe b
myLookup _ [] = Nothing
myLookup key ((k, v):xs)
| key == k = Just v
| otherwise = myLookup key xs
OUTPUT:
12. Write a program that prints the integers from 1 to 100 (inclusive). But: for multiples of
three, print NIT (instead of the number) for multiples of five, print Andhra (instead of
the number) for multiples of both three and five, print NITAndhra (instead of the
number)
CODE:
printNumbers :: IO ()
printNumbers = mapM_ putStrLn $ map fizzBuzz [1..100]
where
fizzBuzz n
| n `mod` 15 == 0 = "NITAndhra"
| n `mod` 3 == 0 = "NIT"
| n `mod` 5 == 0 = "Andhra"
| otherwise = show n
OUTPUT:
13. Rosie has recently learned about ASCII values. She is very fond of experimenting.
With his
knowledge of ASCII values and characters. She has developed a special word and
named it
Rosie's Magical word. A word that consists of alphabets whose ASCII value is a
prime
number is Rosie's Magical word. An alphabet is Rosie's Magical alphabet if its
ASCII value is
prime. convert The given strings to Rosie's Magical Word.
Rules for converting:
1. Each character should be replaced by The nearest Rosie's Magical alphabet.
2. If the character is equidistant with 2 Magical alphabets. The one with a lower ASCII
value
will be considered as its replacement.
Input:
AFREEN
Output:
CGSCCO
Explanation
ASCII values of alphabets in AFREEN are 65, 70, 82, 69, 69 and 78 respectively which
are
converted to CGSCCO with ASCII values 67, 71, 83, 67, 67, 79 respectively. All such
ASCII
values are prime numbers.
CODE:
import Data.List (minimumBy)
import Data.Ord (comparing)
OUTPUT:
14. n people standing in a circle in order from 1 to n. if n=5 and then No. 1 has a sword.
He kills
the next person (i.e. No. 2) and gives the sword to the next (i.e. No. 3). All people do the
same until only 1 survives. Which number survives at the last? Note: Initially knife will be
with the first person (i.e. No. 1)
Input:
100
Output:
73
CODE:
josephus :: Int -> Int
josephus n = 1 + 2 * (n - highestPowerOf2)
where
highestPowerOf2 = 2 ^ (floor $ logBase 2 (fromIntegral n))
OUTPUT:
1
11
121
1331
14641
CODE:
pascal :: Int -> [[Int]]
pascal 0 = [[1]]
pascal n = pascal (n - 1) ++ [nextRow (last $ pascal (n - 1))]
where
nextRow prevRow = zipWith (+) ([0] ++ prevRow) (prevRow ++ [0])
OUTPUT:
17. Given an array of strings strs, group the anagrams together. You can return the
answer in
any order. An Anagram is a word or phrase formed by rearranging the letters of a
different
word or phrase, typically using all the original letters exactly once.
Input:
["eat","tea","tan","ate","nat",&qu
ot;bat"]
Output:
[["bat"],["nat","tan"],["ate","eat",
"tea"]]
Given an integer array nums, find the contiguous subarray (containing at least one
number)
which has the largest sum and return its sum.
CODE:
import Data.List (sort)
import Data.Map (fromListWith, elems)