0% found this document useful (0 votes)
4 views

Lab Haskell Programs 2

The document outlines programming assignments for the course 'Principles of Programming Languages' (19CSE313), focusing on Haskell programming. It includes various tasks such as writing functions for basic operations, recursion, list manipulation, and implementing algorithms like GCD and safe division. Each task provides a brief description, the corresponding Haskell code, and instructions for execution.

Uploaded by

Arjun Das
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Lab Haskell Programs 2

The document outlines programming assignments for the course 'Principles of Programming Languages' (19CSE313), focusing on Haskell programming. It includes various tasks such as writing functions for basic operations, recursion, list manipulation, and implementing algorithms like GCD and safe division. Each task provides a brief description, the corresponding Haskell code, and instructions for execution.

Uploaded by

Arjun Das
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Principles of Programming Languages (19CSE313)

Principles of Programming Languages (19CSE313)

Semester: VI

Unit-1
Haskel Programs

Prepared By:

Dr. Amulyashree S Dr. Daddala Yasoomkari


Assistant Professor, Assistant Professor,
Amrita School of Computing, Amrita School of Computing,
Amrita Vishwa Vidyapeetham, Amrita Vishwa Vidyapeetham,
Bengaluru Campus Bengaluru Campus

1. Write a Haskell program to take an integer from user and add 10 to it, followed by displaying
the result

-- Add 10 to input number


addTen :: Int -> Int
addTen x = x + 10

-- Main function to get input from the user and print the result
main :: IO ()
main = do
putStrLn "Enter an integer:"
input <- getLine
let number = read input :: Int
print (addTen number)

Steps to run in GHCi:


✓ Open ghci.
✓ Type the code into the GHCi prompt or load a .hs file containing
it using :load <filename>.hs.
✓ Call the main function in GHCi: main.

2. Write a program that calculates the factorial of a number using recursion.

factorial :: Integer -> Integer

1
Principles of Programming Languages (19CSE313)

factorial 0 = 1
factorial n = n * factorial (n - 1)

main :: IO ()
main = do
putStrLn "Enter a number to calculate its factorial:"
input <- getLine
let num = read input :: Integer
print (factorial num)

3. Write a program that checks whether a given number is prime.

isPrime :: Integer -> Bool


isPrime n
| n <= 1 = False
| otherwise = null [x | x <- [2..n-1], n `mod` x == 0]

main :: IO ()
main = do
putStrLn "Enter a number to check if it's prime:"
input <- getLine
let num = read input :: Integer
if isPrime num
then putStrLn "Yes, it's a prime number!"
else putStrLn "No, it's not a prime number."
4. Write a program that sums all the even numbers in a list.

sumEven :: [Int] -> Int


sumEven [] = 0
sumEven (x:xs)
| even x = x + sumEven xs
| otherwise = sumEven xs

main :: IO ()
main = do
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print ("Sum of even numbers: " ++ show (sumEven numbers))

5. Write a program that calculates the nth Fibonacci number.

fibonacci :: Integer -> Integer


fibonacci 0 = 0
fibonacci 1 = 1
fibonacci n = fibonacci (n - 1) + fibonacci (n - 2)

main :: IO ()
main = do
putStrLn "Enter a number to get the Fibonacci number:"
input <- getLine
let num = read input :: Integer
print (fibonacci num)

2
Principles of Programming Languages (19CSE313)

6. Write a program that reverses a string input by the user.

reverseString :: String -> String


reverseString = reverse

main :: IO ()
main = do
putStrLn "Enter a string to reverse:"
input <- getLine
putStrLn ("Reversed string: " ++ reverseString input)

7. Write a program that checks if a string is a palindrome

isPalindrome :: String -> Bool


isPalindrome s = s == reverse s

main :: IO ()
main = do
putStrLn "Enter a string to check if it's a palindrome:"
input <- getLine
if isPalindrome input
then putStrLn "Yes, it's a palindrome!"
else putStrLn "No, it's not a palindrome."

8. Write a program that filters and squares all the even numbers from a list

evenSquares :: [Int] -> [Int]


evenSquares xs = [x^2 | x <- xs, even x]

main :: IO ()
main = do
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print ("Squares of even numbers: " ++ show (evenSquares
numbers))

9. Write a program that computes the sum of digits of a given number.

sumOfDigits :: Integer -> Integer


sumOfDigits n
| n < 10 = n
| otherwise = n `mod` 10 + sumOfDigits (n `div` 10)

main :: IO ()
main = do
putStrLn "Enter a number to calculate the sum of its digits:"
input <- getLine
let num = read input :: Integer
print ("Sum of digits: " ++ show (sumOfDigits num))

3
Principles of Programming Languages (19CSE313)

10. Write a program that merges two lists into a single list.

mergeLists :: [Int] -> [Int] -> [Int]


mergeLists xs ys = xs ++ ys

main :: IO ()
main = do
let list1 = [1, 2, 3]
let list2 = [4, 5, 6]
print ("Merged List: " ++ show (mergeLists list1 list2))

11. Write a program that finds the maximum number in a list of integers.

findMax :: [Int] -> Int


findMax [] = error "Empty list"
findMax [x] = x
findMax (x:xs) = max x (findMax xs)

main :: IO ()
main = do
let numbers = [10, 20, 50, 40, 30]
print ("Maximum number: " ++ show (findMax numbers))

12. Write a program that sorts a list of integers in ascending order.

import Data.List (sort)

sortList :: [Int] -> [Int]


sortList = sort

main :: IO ()
main = do
let numbers = [5, 2, 8, 1, 6, 3]
print ("Sorted List: " ++ show (sortList numbers))

13. Write a program that counts how many times a specific element appears in a list.

countOccurrences :: Eq a => a -> [a] -> Int


countOccurrences x = length . filter (== x)

main :: IO ()
main = do
let numbers = [1, 2, 2, 3, 3, 3, 4]
print ("Occurrences of 3: " ++ show (countOccurrences 3
numbers))

14. Write a program that zips two lists into a list of tuples.

zipLists :: [a] -> [b] -> [(a, b)]


zipLists [] _ = []
zipLists _ [] = []

4
Principles of Programming Languages (19CSE313)

zipLists (x:xs) (y:ys) = (x, y) : zipLists xs ys

main :: IO ()
main = do
let list1 = [1, 2, 3]
let list2 = ['a', 'b', 'c']
print ("Zipped List: " ++ show (zipLists list1 list2))

15. Write a program that applies a given function to each element of a list.

squareList :: [Int] -> [Int]


squareList = map (^2)

main :: IO ()
main = do
let numbers = [1, 2, 3, 4, 5]
print ("Squared List: " ++ show (squareList numbers))

16. Write a program that filters out odd numbers from a list of integers.

filterOddNumbers :: [Int] -> [Int]


filterOddNumbers = filter even

main :: IO ()
main = do
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print ("Even numbers: " ++ show (filterOddNumbers numbers))

17. Write a program that calculates the sum of the first elements of a list of tuples.

sumFirstElements :: Num a => [(a, b)] -> a


sumFirstElements = sum . map fst

main :: IO ()
main = do
let tuples = [(1, "a"), (2, "b"), (3, "c")]
print ("Sum of first elements: " ++ show (sumFirstElements
tuples))

18. Write a program that computes the length of a list without using the built-in length function

myLength :: [a] -> Int


myLength [] = 0
myLength (_:xs) = 1 + myLength xs

main :: IO ()
main = do
let numbers = [1, 2, 3, 4, 5]
print ("Length of list: " ++ show (myLength numbers))

19. Write a program to find the maximum number in a list.

5
Principles of Programming Languages (19CSE313)

findMax :: Ord a => [a] -> a


findMax [] = error "Empty list"
findMax [x] = x
findMax (x:xs) = max x (findMax xs)

main :: IO ()
main = do
let numbers = [10, 5, 20, 15]
print ("Maximum element: " ++ show (findMax numbers))

20. Write a program that removes duplicate elements from a list.

removeDuplicates :: Eq a => [a] -> [a]


removeDuplicates [] = []
removeDuplicates (x:xs) = x : removeDuplicates (filter (/= x) xs)

main :: IO ()
main = do
let numbers = [1, 2, 2, 3, 4, 4, 5]
print ("List without duplicates: " ++ show (removeDuplicates
numbers))

21. Write a program that returns the nth element of a list.

nthElement :: [a] -> Int -> a


nthElement (x:_) 0 = x
nthElement (_:xs) n = nthElement xs (n - 1)

main :: IO ()
main = do
let numbers = [10, 20, 30, 40, 50]
print ("Element at index 2: " ++ show (nthElement numbers 2))

22. Write a program that applies a function to both elements of a tuple in a list of tuples.

mapTuple :: (a -> b, c -> d) -> [(a, c)] -> [(b, d)]


mapTuple (f, g) = map (\(x, y) -> (f x, g y))

main :: IO ()
main = do
let tuples = [(1, 2), (3, 4), (5, 6)]
let result = mapTuple ((+1), (*2)) tuples
print ("Mapped tuples: " ++ show result)

23. Write a program that counts the occurrences of each element in a list.

countOccurrences :: Eq a => [a] -> [(a, Int)]


countOccurrences [] = []
countOccurrences (x:xs) = (x, count x xs + 1) : countOccurrences
(filter (/= x) xs)

6
Principles of Programming Languages (19CSE313)

where
count y = length . filter (== y)

main :: IO ()
main = do
let numbers = [1, 2, 2, 3, 3, 3, 4]
print ("Element counts: " ++ show (countOccurrences numbers))

24. Write a program that flattens a list of lists into a single list.

flatten :: [[a]] -> [a]


flatten = concat

main :: IO ()
main = do
let nestedList = [[1, 2], [3, 4], [5, 6]]
print ("Flattened list: " ++ show (flatten nestedList))

25. Write a program to calculate the power of a number using recursion.

power :: Integer -> Integer -> Integer


power _ 0 = 1
power base exp = base * power base (exp - 1)

main :: IO ()
main = do
putStrLn "Enter base and exponent:"
baseInput <- getLine
expInput <- getLine
let base = read baseInput :: Integer
exp = read expInput :: Integer
print ("Result: " ++ show (power base exp))

26. Write a program to calculate the greatest common divisor (GCD) of two numbers using
Euclid's algorithm.

gcd' :: Integer -> Integer -> Integer


gcd' a 0 = a
gcd' a b = gcd' b (a `mod` b)

main :: IO ()
main = do
putStrLn "Enter two numbers to compute their GCD:"
aInput <- getLine
bInput <- getLine
let a = read aInput :: Integer
b = read bInput :: Integer
print ("GCD: " ++ show (gcd' a b))

27. Write a program that maps a function over a Maybe value.

7
Principles of Programming Languages (19CSE313)

mapMaybe :: (a -> b) -> Maybe a -> Maybe b


mapMaybe _ Nothing = Nothing
mapMaybe f (Just x) = Just (f x)

main :: IO ()
main = do
let maybeVal = Just 5
print ("Mapped Maybe value: " ++ show (mapMaybe (*2)
maybeVal))
print ("Mapped Nothing: " ++ show (mapMaybe (*2) Nothing))

28. Write a program to check if a list of integers is sorted in ascending order.

isSorted :: (Ord a) => [a] -> Bool


isSorted [] = True
isSorted [x] = True
isSorted (x:y:xs)
| x <= y = isSorted (y:xs)
| otherwise = False

main :: IO ()
main = do
let numbers = [1, 2, 3, 4, 5]
print ("Is sorted: " ++ show (isSorted numbers))
let unsortedNumbers = [1, 3, 2, 4]
print ("Is sorted: " ++ show (isSorted unsortedNumbers))

29. Write a program that divides two numbers safely, returning Nothing if the denominator is
zero.

safeDiv :: (Eq a, Fractional a) => a -> a -> Maybe a


safeDiv _ 0 = Nothing
safeDiv x y = Just (x / y)

main :: IO ()
main = do
print ("Safe division result: " ++ show (safeDiv 10 2))
print ("Safe division result: " ++ show (safeDiv 10 0))

30. Write a program that defines a simple functor and applies a function to its value.

data Box a = Box a

instance Functor Box where


fmap f (Box x) = Box (f x)

main :: IO ()
main = do
let boxVal = Box 5
print ("Box after applying fmap: " ++ show (fmap (*2)
boxVal))

8
Principles of Programming Languages (19CSE313)

31. Write a program that filters a list of tuples based on a condition and then applies a function
to the filtered list.

filterAndMap :: [(Int, String)] -> [(Int, String)]


filterAndMap xs = map (\(x, y) -> (x, reverse y)) (filter (\(x,
_) -> x >= 5) xs)

main :: IO ()
main = do
let tuples = [(1, "apple"), (6, "banana"), (4, "cherry"), (7,
"date")]
print ("Filtered and mapped tuples: " ++ show (filterAndMap
tuples))

32. Write a program that merges two sorted lists into one sorted list.

mergeSorted :: (Ord a) => [a] -> [a] -> [a]


mergeSorted [] ys = ys
mergeSorted xs [] = xs
mergeSorted (x:xs) (y:ys)
| x <= y = x : mergeSorted xs (y:ys)
| otherwise = y : mergeSorted (x:xs) ys

main :: IO ()
main = do
let list1 = [1, 3, 5, 7]
let list2 = [2, 4, 6, 8]
print ("Merged sorted list: " ++ show (mergeSorted list1
list2))

33. Write a program that generates all possible subsets of a list.

subsets :: [a] -> [[a]]


subsets [] = [[]]
subsets (x:xs) = subsets xs ++ map (x:) (subsets xs)

main :: IO ()
main = do
let list = [1, 2, 3]
print ("All subsets: " ++ show (subsets list))

34. Write a program to find the intersection of two lists.

intersection :: Eq a => [a] -> [a] -> [a]


intersection xs ys = [x | x <- xs, x `elem` ys]

main :: IO ()
main = do
let list1 = [1, 2, 3, 4]
let list2 = [3, 4, 5, 6]

9
Principles of Programming Languages (19CSE313)

print ("Intersection: " ++ show (intersection list1 list2))

35. Write a program that counts the frequency of each element in a list.

countFrequency :: Eq a => [a] -> [(a, Int)]


countFrequency [] = []
countFrequency (x:xs) = (x, count x (x:xs)) : countFrequency
(filter (/= x) xs)
where
count x = length . filter (== x)

main :: IO ()
main = do
let numbers = [1, 2, 2, 3, 3, 3, 4]
print ("Element frequencies: " ++ show (countFrequency
numbers))

36. Write a program to define a binary tree and calculate its size (number of nodes).

data Tree a = Empty | Node a (Tree a) (Tree a)

size :: Tree a -> Int


size Empty = 0
size (Node _ left right) = 1 + size left + size right

main :: IO ()
main = do
let tree = Node 1 (Node 2 Empty Empty) (Node 3 Empty Empty)
print ("Size of the tree: " ++ show (size tree))

37. Write a program to check if a binary tree is balanced. A balanced tree is one where the
height difference between the left and right subtrees is at most 1.

data Tree a = Empty | Node a (Tree a) (Tree a)

height :: Tree a -> Int


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

isBalanced :: Tree a -> Bool


isBalanced Empty = True
isBalanced (Node _ left right) = abs (height left - height right)
<= 1
&& isBalanced left
&& isBalanced right

main :: IO ()
main = do
let balancedTree = Node 1 (Node 2 Empty Empty) (Node 3 Empty
Empty)
let unbalancedTree = Node 1 (Node 2 (Node 3 Empty Empty)

10
Principles of Programming Languages (19CSE313)

Empty) Empty
print ("Is balanced: " ++ show (isBalanced balancedTree))
print ("Is balanced: " ++ show (isBalanced unbalancedTree))

38. Write a simple parser to convert a string to an integer.

parseInt :: String -> Maybe Int


parseInt str
| all (`elem` "0123456789") str = Just (read str)
| otherwise = Nothing

main :: IO ()
main = do
print ("Parsed integer: " ++ show (parseInt "123"))
print ("Parsed integer: " ++ show (parseInt "abc"))

39. Write a program that lifts a function to work on Maybe values. This is like applying fmap
to a Maybe.

liftMaybe :: (a -> b) -> Maybe a -> Maybe b


liftMaybe f Nothing = Nothing
liftMaybe f (Just x) = Just (f x)

main :: IO ()
main = do
print ("Lifted function: " ++ show (liftMaybe (*2) (Just 5)))
print ("Lifted function: " ++ show (liftMaybe (*2) Nothing))

40. Write a program that demonstrates a simple Logger monad, which appends logs as it runs.

import Control.Monad

newtype Logger a = Logger { runLogger :: (a, String) }

instance Functor Logger where


fmap f (Logger (x, log)) = Logger (f x, log)

instance Applicative Logger where


pure x = Logger (x, "")
Logger (f, log1) <*> Logger (x, log2) = Logger (f x, log1 ++
log2)

instance Monad Logger where


return = pure
Logger (x, log) >>= f = let Logger (y, newLog) = f x in
Logger (y, log ++ newLog)

logMessage :: String -> Logger ()


logMessage msg = Logger ((), msg)

main :: IO ()

11
Principles of Programming Languages (19CSE313)

main = do
let result = runLogger $ do
logMessage "Starting computation."
logMessage "Computation complete."
return 42
print result

41. Write a program that partitions a list into two lists: one with elements that satisfy a
predicate and one with elements that do not.

partitionList :: (a -> Bool) -> [a] -> ([a], [a])


partitionList pred xs = (filter pred xs, filter (not . pred) xs)

main :: IO ()
main = do
let numbers = [1, 2, 3, 4, 5, 6]
let (even, odd) = partitionList even numbers
print ("Even numbers: " ++ show even)
print ("Odd numbers: " ++ show odd)

42. Write a program to read and write contents to a file

import System.IO

main :: IO ()
main = do
-- Writing to the file
writeFile "example.txt" "Hello, this is a simple file
operation example in Haskell!\n"
putStrLn "Text has been written to 'example.txt'."

-- Reading from the file


content <- readFile "example.txt"
putStrLn "Content read from 'example.txt':"
putStrLn content

43. Write a program to perform CPU scheduling using FCFS algorithm

-- FCFS Scheduling Algorithm


data Process = Process { processId :: Int, arrivalTime :: Int,
burstTime :: Int } deriving Show

-- Function to calculate completion time, waiting time, and


turnaround time
fcfsScheduling :: [Process] -> [(Int, Int, Int)] -- (ProcessId,
Waiting Time, Turnaround Time)
fcfsScheduling processes = calculateStats sortedProcesses 0 0 0
where
sortedProcesses = sortBy (\a b -> compare (arrivalTime a)
(arrivalTime b)) processes

12
Principles of Programming Languages (19CSE313)

calculateStats [] _ _ _ = []
calculateStats (p:ps) prevCompletion prevWaiting
prevTurnaround =
let completion = prevCompletion + burstTime p
waiting = prevCompletion - arrivalTime p
turnaround = waiting + burstTime p
in (processId p, waiting, turnaround) : calculateStats ps
completion waiting turnaround

main :: IO ()
main = do
let processes = [Process 1 0 5, Process 2 1 3, Process 3 2 8,
Process 4 3 6]
let stats = fcfsScheduling processes
mapM_ print stats

44. Write a program to perform CPU scheduling using SJF algorithm

-- SJF Scheduling Algorithm


data Process = Process { processId :: Int, arrivalTime :: Int,
burstTime :: Int } deriving Show

-- Function to calculate completion time, waiting time, and


turnaround time
sjfScheduling :: [Process] -> [(Int, Int, Int)] -- (ProcessId,
Waiting Time, Turnaround Time)
sjfScheduling processes = calculateStats sortedProcesses 0 0 0
where
sortedProcesses = sortBy (\a b -> compare (burstTime a)
(burstTime b)) processes

calculateStats [] _ _ _ = []
calculateStats (p:ps) prevCompletion prevWaiting
prevTurnaround =
let completion = prevCompletion + burstTime p
waiting = prevCompletion - arrivalTime p
turnaround = waiting + burstTime p
in (processId p, waiting, turnaround) : calculateStats ps
completion waiting turnaround

main :: IO ()
main = do
let processes = [Process 1 0 6, Process 2 1 8, Process 3 2 7,
Process 4 3 3]
let stats = sjfScheduling processes
mapM_ print stats

45. Write a program to perform CPU scheduling using Round-robin algorithm

-- Round Robin Scheduling Algorithm


data Process = Process { processId :: Int, arrivalTime :: Int,

13
Principles of Programming Languages (19CSE313)

burstTime :: Int, remainingTime :: Int } deriving Show

-- Function to simulate Round Robin scheduling


roundRobinScheduling :: [Process] -> Int -> [Int] -- Time
quantum is the second argument
roundRobinScheduling processes quantum = roundRobinHelper
processes quantum [] 0
where
roundRobinHelper [] _ completed _ = completed
roundRobinHelper (p:ps) q completed time
| remainingTime p <= q = roundRobinHelper ps q (completed
++ [processId p]) (time + remainingTime p)
| otherwise = roundRobinHelper (ps ++ [p { remainingTime
= remainingTime p - q }]) q completed (time + q)

main :: IO ()
main = do
let processes = [Process 1 0 10 10, Process 2 0 5 5, Process
3 0 8 8]
let timeQuantum = 4
let completed = roundRobinScheduling processes timeQuantum
putStrLn "Process execution order:"
mapM_ print completed

46. Write a program to perform CPU scheduling using priority scheduling algorithm

-- Priority Scheduling Algorithm


data Process = Process { processId :: Int, arrivalTime :: Int,
burstTime :: Int, priority :: Int } deriving Show

-- Function to calculate completion time, waiting time, and


turnaround time
priorityScheduling :: [Process] -> [(Int, Int, Int)] --
(ProcessId, Waiting Time, Turnaround Time)
priorityScheduling processes = calculateStats sortedProcesses 0 0
0
where
sortedProcesses = sortBy (\a b -> compare (priority a)
(priority b)) processes

calculateStats [] _ _ _ = []
calculateStats (p:ps) prevCompletion prevWaiting
prevTurnaround =
let completion = prevCompletion + burstTime p
waiting = prevCompletion - arrivalTime p
turnaround = waiting + burstTime p
in (processId p, waiting, turnaround) : calculateStats ps
completion waiting turnaround

main :: IO ()
main = do

14
Principles of Programming Languages (19CSE313)

let processes = [Process 1 0 6 2, Process 2 1 8 1, Process 3


2 7 3, Process 4 3 5 4]
let stats = priorityScheduling processes
mapM_ print stats

47. Write a program to implement a solution for TSP problem

import Data.List
import Data.Function (on)

-- Define a type for a city as a tuple (x, y)


type City = (Int, Int)

-- Calculate the Euclidean distance between two cities


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

-- Calculate the total length of a path (list of cities)


totalDistance :: [City] -> Double
totalDistance cities = sum (zipWith distance cities (tail cities
++ [head cities]))

-- Brute force solution to the TSP problem


bruteForceTSP :: [City] -> ([City], Double)
bruteForceTSP cities = minimumBy (compare `on` snd) allPaths
where
-- Generate all permutations of the cities
allPaths = [(path, totalDistance path) | path <- permutations
cities]

-- Example usage
main :: IO ()
main = do
let cities = [(0, 0), (1, 2), (2, 4), (3, 1)] -- Example
list of cities
let (optimalPath, minDistance) = bruteForceTSP cities
putStrLn "Optimal path:"
print optimalPath
putStrLn $ "Total distance: " ++ show minDistance

15

You might also like