0% found this document useful (0 votes)
5 views26 pages

HASKELL

The document is an assignment on Haskell programming, covering various tasks such as explaining the difference between Char and String types, evaluating functions, defining new functions, and implementing specific functionalities like sorting and checking equality of pairs. It includes code examples and expected outputs for each task, demonstrating the use of Haskell syntax and functions. The assignment also addresses error handling and type mismatches in expressions.

Uploaded by

Haswanth Petla
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views26 pages

HASKELL

The document is an assignment on Haskell programming, covering various tasks such as explaining the difference between Char and String types, evaluating functions, defining new functions, and implementing specific functionalities like sorting and checking equality of pairs. It includes code examples and expected outputs for each task, demonstrating the use of Haskell syntax and functions. The assignment also addresses error handling and type mismatches in expressions.

Uploaded by

Haswanth Petla
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 26

TDPL ASSIGNMENT-3

NAME:HASWANTH
ROLL NO:422238
SECTION:B

HASKELL LAB TASK 1


1. What is the difference between the type Char and the type String? Do the two
expressions "a" and 'a' represent the same value?
The types `Char` and `String` in Haskell are different:

- **Char**: This type represents a single character, such as `'a'`. It is enclosed in single
quotes.

- **String**: This type represents a sequence of characters and is essentially a list of


`Char` values. For example, `"a"` is a string containing one character, which is equivalent
to the list `['a']` and is enclosed in double 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.

2. Given the function definition

function_name :: argument_type -> return_type

3. square :: Int -> Int


square x = x * x
and the previous definitions of inc and double. What is the value of
1. inc (square 5)
2. square (inc 5)
3. average (inc 3) (inc 5)

SOLUTION:

1. `square :: Int -> Int`


`square x = x * x`
This function takes an integer `x` and returns its square.

2. `inc :: Int -> Int`


`inc x = x + 1`
This function increments the integer `x` by 1.

3. `double :: Int -> Int`


`double x = 2 * x`
This function multiplies the integer `x` by 2.

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`

Now, let's evaluate each expression:


### 1. `inc (square 5)`

- First, calculate `square 5`:


\[
square(5) = 5 * 5 = 25
\]
- Then, apply `inc` to 25:
\[
inc(25) = 25 + 1 = 26
\]
- **Value**: `26`

### 2. `square (inc 5)`

- First, calculate `inc 5`:


\[
inc(5) = 5 + 1 = 6
\]
- Then, apply `square` to 6:
\[
square(6) = 6 * 6 = 36
\]
- **Value**: `36`

### 3. `average (inc 3) (inc 5)`

- First, calculate `inc 3` and `inc 5`:


\[
inc(3) = 3 + 1 = 4
\]
\[
inc(5) = 5 + 1 = 6
\]
- Then, calculate the average of 4 and 6:
\[
average(4, 6) = (4 + 6) `div` 2 = 10 `div` 2 = 5
\]
- **Value**: `5`

### Summary:

1. `inc (square 5)` evaluates to `26`.


2. `square (inc 5)` evaluates to `36`.
3. `average (inc 3) (inc 5)` evaluates to `5`.

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:

square :: Num a => a -> a


This means `square` can take any numeric type (like `Int` or `Float`) as input and will
return a value of that same type. You can check this in GHCi by using `:type square` or
`:t square`.

5. Which of the following identifiers can be function or variable names?


o square_1
o 1square
o Square
o square!
o square'
If you are unsure, replace the function name in your square definition from Exercise 2
with each of these identifiers to see whether the compiler complains and what the error
message looks like.

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

-- Main function to test showResult


main :: IO ()
main = do
putStrLn (showResult 123) -- Should output: "The result is 123"
putStrLn (showResult 456) -- Should output: "The result is 456"
putStrLn (showResult 789) -- Should output: "The result is 789"

Output:

3. Write a function showAreaOfCircle which, given the radius of a circle,


calculates the area of the circle, showAreaOfCircle 12.3 ⇒ "The area of a
circle with radius 12.3cm is about 475.2915525615999 cm^2" Use the show
function, as well as the predefined value pi :: Floating a => a to write
showAreaOfCircle.
Code:showAreaOfCircle :: (Floating a, Show a) => a -> String
showAreaOfCircle radius =
"The area of a circle with radius " ++ show radius ++
" cm is about " ++ show area ++ " cm^2"
where
area = pi * radius ^ 2

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.

### 1. **First implementation (using `&&` and `||`):**

```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.

### 2. **Second implementation (simplified guard version):**

```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.

### 4. **Fourth implementation (nested `if` statements):**

```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
```

- This version uses `if` statements to implement the same logic.


- While it is technically correct, this version is more verbose and less elegant than the previous
implementations.
- **Correct behavior:** The function works but is more complex than necessary.

### 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 ..]

-- Division function using multiples


divide :: Int -> Int -> Int
divide divisor dividend = length (multiplesUpTo divisor dividend)
OUTPUT:
9. Define the function length :: [a] -&gt; Int. It is quite similar to sum and product in the
way it traverses its input list. Since length is defined in the Prelude, don&#39;t forget to hide it
by adding the line
import Prelude hiding (length)
CODE:
import Prelude hiding (length)

-- Define the length function


length :: [a] -> Int
length [] = 0
length (_:xs) = 1 + length xs
OUTPUT:

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:[&#39;a&#39;,&#39;b&#39;]
&quot;abc&quot;++&quot;cd&quot;
&quot;a&quot;:&quot;bCc&quot;
&quot;a&quot; ++ &quot;bCc&quot;
&#39;a&#39;:&#39;b&#39;
&#39;a&#39;:&quot;b&quot;
[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 `:`.

### 4. `[1,2,3] ++ [4..7]`


- **Type**: `[Int]` (list of integers)
- **Value**: `[1, 2, 3, 4, 5, 6, 7]`
- **Explanation**: This expression is valid. The `++` operator concatenates two lists, so the result is a
list that combines both `[1, 2, 3]` and `[4..7]`.

### 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.

### 6. `"abc" ++ "cd"`


- **Type**: `String` (which is a synonym for `[Char]`)
- **Value**: `"abccd"`
- **Explanation**: This expression is valid. It concatenates the two strings `"abc"` and `"cd"` using the
`++` operator, resulting in `"abccd"`.

### 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"`.

### 8. `"a" ++ "bCc"`


- **Type**: `String` (which is a synonym for `[Char]`)
- **Value**: `"abCc"`
- **Explanation**: This expression is valid. It concatenates the two strings `"a"` and `"bCc"` using the
`++` operator, resulting in `"abCc"`.

### 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).

### 10. `'a':"b"`


- **Type**: `String` (which is a synonym for `[Char]`)
- **Value**: `"ab"`
- **Explanation**: This expression is valid. The character `'a'` is prepended to the string `"b"`,
resulting in the string `"ab"`.

### 11. `[1,4,7] ++ 4:[5:[]]`


- **Type**: `[Int]` (list of integers)
- **Value**: `[1, 4, 7, 4, 5]`
- **Explanation**: This is valid. The list `[1, 4, 7]` is concatenated with the list formed by `4 : [5 : []]`,
which is equivalent to `[4, 5]`. The result is `[1, 4, 7, 4, 5]`.

### 12. `[True,True:[]]`


- **Error**: **Type mismatch**
- **Explanation**: This gives an error because `True:[]` is a list, and `[True, True:[]]` is trying to mix a
`Bool` (`True`) and a list (`True:[]`) in the same list. Lists must contain elements of the same type.

### 13. `True:[True,False]`


- **Type**: `[Bool]` (list of booleans)
- **Value**: `[True, True, False]`
- **Explanation**: This expression is valid. The `True` is prepended to the list `[True, False]`, resulting
in `[True, True, False]`.

---

### Summary of Results:


- **Valid Expressions**:
1. `1:[2,3,4]` → `[1, 2, 3, 4]`
2. `1:2:3:4:[]` → `[1, 2, 3, 4]`
4. `[1,2,3] ++ [4..7]` → `[1, 2, 3, 4, 5, 6, 7]`
6. `"abc" ++ "cd"` → `"abccd"`
8. `"a" ++ "bCc"` → `"abCc"`
10. `'a':"b"` → `"ab"`
11. `[1,4,7] ++ 4:[5:[]]` → `[1, 4, 7, 4, 5]`
13. `True:[True,False]` → `[True, True, False]`

- **Expressions with Errors**:


3. `[1,2,3]:[4..7]` → **Type mismatch** (`:` expects a single element on the left)
5. `1:['a','b']` → **Type mismatch** (combining an `Int` with a `[Char]`)
7. `"a":"bCc"` → **Type mismatch** (using `(:)` with a string instead of a character)
9. `'a':'b'` → **Type mismatch** (`(:)` requires the second operand to be a list)
12. `[True,True:[]]` → **Type mismatch** (combining a `Bool` with a `[Bool]`)

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).

Recursive Definition of Factorial:


The recursive definition of the factorial function fact(n)fact(n)fact(n) can be expressed
as:

fact(n)=n×fact(n−1)fact(n) = n \times fact(n-1)fact(n)=n×fact(n−1)

Where the base case is:


fact(1)=1fact(1) = 1fact(1)=1

CODE:
Factorial Function (Without Error Case):
fact :: (Eq a, Num a) => a -> a
fact 1 = 1
fact n = n * fact (n - 1)

Why is fact a Partial Function?


A partial function is a function that is not defined for all possible inputs in its domain.
In this case, the function fact is partial because it does not handle non-positive numbers
(e.g., n = 0 or negative integers). If we input a negative number, the function will keep
calling itself indefinitely, resulting in a stack overflow.
We need to make the function total by handling invalid inputs (like non-positive numbers)
with an error case.

Factorial Function (With Error Case):


To make the function total, we can add an error case for non-positive inputs using
Haskell’s error function.

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)

-- Recursive function to generate a list from m to n


enumFromTo :: (Ord a, Enum a) => a -> a -> [a]
enumFromTo m n
| m > n = [] -- Base case: if m is greater than n, return an empty list
| otherwise = m : enumFromTo (succ m) n -- Recursive case: add m to the list and call for m+1

-- Main function to test enumFromTo


main :: IO ()
main = do
putStrLn "Generating list from 3 to 7:"
print (enumFromTo 3 7) -- Should output [3,4,5,6,7]

putStrLn "Generating list from 5 to 5:"


print (enumFromTo 5 5) -- Should output [5]

putStrLn "Generating list from 10 to 7:"


print (enumFromTo 10 7) -- Should output []
OUTPUT:

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 -&gt; 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

-- Main function to test countOdds


main :: IO ()
main = do
putStrLn "Count of odd numbers in [1, 6, 9, 14, 16, 22]:"
print (countOdds [1, 6, 9, 14, 16, 22]) -- Should output 2

putStrLn "Count of odd numbers in [2, 4, 6, 8]:"


print (countOdds [2, 4, 6, 8]) -- Should output 0
putStrLn "Count of odd numbers in [1, 3, 5, 7, 9]:"
print (countOdds [1, 3, 5, 7, 9]) -- Should output 5

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

-- Main function to test removeOdd


main :: IO ()
main = do
putStrLn "Removing odd numbers from [1, 4, 5, 7, 10]:"
print (removeOdd [1, 4, 5, 7, 10]) -- Should output [4, 10]

putStrLn "Removing odd numbers from [2, 4, 6, 8]:"


print (removeOdd [2, 4, 6, 8]) -- Should output [2, 4, 6, 8]

putStrLn "Removing odd numbers from [1, 3, 5, 7, 9]:"


print (removeOdd [1, 3, 5, 7, 9]) -- Should output []
OUTPUT:

15. Challenge: At the end of the last screencast, demonstrating the implementation
of closestPoint :: Point -&gt; [Point] -&gt; 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)

-- Distance function to calculate the distance between two points


distance :: Point -> Point -> Double
distance (x1, y1) (x2, y2) = sqrt ((x1 - x2) ^ 2 + (y1 - y2) ^ 2)

-- Improved closestPoint function


closestPoint :: Point -> [Point] -> Point
closestPoint _ [] = error "No points provided"
closestPoint p points = snd $ minimum distances
where
distances = [(distance p point, point) | point <- points]

-- Main function to test closestPoint


main :: IO ()
main = do
let targetPoint = (0, 0) -- Target point
points = [(1, 2), (3, 4), (5, 6), (1, 1), (2, 2)] -- List of points
print $ closestPoint targetPoint points -- Output the closest point
OUTPUT:

16. mplement a function colouredFTree :: Float -&gt; Int -&gt; Colour -&gt; Line -&gt;
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:

3. Implement a function that computes the nth Fibonacci number


CODE:
fibonacci :: Int -> Int
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci n = fibonacci (n - 1) + fibonacci (n - 2)
OUTPUT:

4. Implement a function factors that takes an Int and returns a list off all its factors (i.e. all
the Int&#39;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 &lt;= to the value, and the second list being all
elements &gt;
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 &quot;height&quot; 3 in the tree) NOTE
the Empty Tree
is of height 0
CODE:
data Tree a = Empty | Node a (Tree a) (Tree a)

treeHeight :: Tree a -> Int


treeHeight Empty = 0
treeHeight (Node _ left right) = 1 + max (treeHeight left) (treeHeight right)

exampleTree :: Tree Char


exampleTree = Node 'a'
(Node 'b'
(Node 'd' Empty Empty)
(Node 'e' Empty Empty))
(Node 'c' Empty Empty)

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&#39;t occur
anywhere in
the list the function returns Nothing
E.x. lookup 2 [(0,&#39;a&#39;),(1,&#39;b&#39;)] == Nothing
lookup 2 [(0,&#39;a&#39;),(2,&#39;b&#39;),(2,&#39;c&#39;)] == Just &#39;b&#39;
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&#39;s Magical word. A word that consists of alphabets whose ASCII value is a
prime
number is Rosie&#39;s Magical word. An alphabet is Rosie&#39;s Magical alphabet if its
ASCII value is
prime. convert The given strings to Rosie&#39;s Magical Word.
Rules for converting:
1. Each character should be replaced by The nearest Rosie&#39;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)

isPrime :: Int -> Bool


isPrime n
| n < 2 = False
| otherwise = null [x | x <- [2..floor (sqrt (fromIntegral n))], n `mod` x == 0]
magicalASCII :: [Int]
magicalASCII = filter isPrime [65..90] -- ASCII values for uppercase letters A-Z

nearestMagical :: Int -> Char


nearestMagical c = toEnum $ minimumBy (comparing distance) magicalASCII
where
distance x = abs (x - c)

rosiesMagicalWord :: String -> String


rosiesMagicalWord = map nearestMagical . map fromEnum

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:

15. Write a function to rotate a list in Haskell by giving a K value.


Input: [1, 2, 3, 4, 5, 6, 7] K=2
Output:[3, 4, 5, 6, 7, 1, 2]
CODE:
rotate :: [a] -> Int -> [a]
rotate xs k = drop k xs ++ take k xs
OUTPUT:
16. Compute Pascal&#39;s triangle up to a given number of rows.In Pascal&#39;s
Triangle each number is
computed by adding the numbers to the right and left of the current position in the
previous
row.
Input:5
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:
[&quot;eat&quot;,&quot;tea&quot;,&quot;tan&quot;,&quot;ate&quot;,&quot;nat&quot;,&qu
ot;bat&quot;]
Output:
[[&quot;bat&quot;],[&quot;nat&quot;,&quot;tan&quot;],[&quot;ate&quot;,&quot;eat&quot;,
&quot;tea&quot;]]
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)

groupAnagrams :: [String] -> [[String]]


groupAnagrams strs = elems $ fromListWith (++) [(sort str, [str]) | str <- strs]
OUTPUT:

18. A subarray is a contiguous part of an array.


Input:[-2,1,-3,4,-1,2,1,-5,4]
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
CODE:
maxSubArray :: [Int] -> Int
maxSubArray xs = maximum $ scanl1 (\acc x -> max x (acc + x)) xs
OUTPUT:

You might also like