In this section, we will explore two fundamental data structures in Haskell: lists and tuples. These structures are essential for handling collections of data and are widely used in functional programming.

Lists

What is a List?

A list in Haskell is a collection of elements of the same type. Lists are one of the most commonly used data structures in Haskell due to their simplicity and versatility.

Creating Lists

You can create a list by enclosing elements in square brackets, separated by commas.

-- A list of integers
numbers :: [Int]
numbers = [1, 2, 3, 4, 5]

-- A list of characters (a string)
greeting :: [Char]
greeting = ['H', 'e', 'l', 'l', 'o']

List Operations

Here are some basic operations you can perform on lists:

  • Concatenation: Combine two lists using the ++ operator.
  • Cons: Add an element to the front of a list using the : operator.
  • Length: Get the number of elements in a list using the length function.
  • Indexing: Access an element by its index using the !! operator.
-- Concatenation
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combinedList = list1 ++ list2  -- [1, 2, 3, 4, 5, 6]

-- Cons
newList = 0 : list1  -- [0, 1, 2, 3]

-- Length
listLength = length list1  -- 3

-- Indexing
secondElement = list1 !! 1  -- 2

Common List Functions

Haskell provides many built-in functions to work with lists:

  • head: Returns the first element of a list.
  • tail: Returns the list without the first element.
  • init: Returns the list without the last element.
  • last: Returns the last element of a list.
  • null: Checks if a list is empty.
  • reverse: Reverses a list.
exampleList = [1, 2, 3, 4, 5]

firstElement = head exampleList  -- 1
restOfList = tail exampleList  -- [2, 3, 4, 5]
allButLast = init exampleList  -- [1, 2, 3, 4]
lastElement = last exampleList  -- 5
isEmpty = null exampleList  -- False
reversedList = reverse exampleList  -- [5, 4, 3, 2, 1]

Tuples

What is a Tuple?

A tuple is a fixed-size collection of elements that can be of different types. Tuples are useful when you want to group different types of data together.

Creating Tuples

You can create a tuple by enclosing elements in parentheses, separated by commas.

-- A tuple with an integer and a string
person :: (Int, String)
person = (25, "Alice")

-- A tuple with three elements of different types
mixedTuple :: (Int, Char, Bool)
mixedTuple = (1, 'a', True)

Accessing Tuple Elements

You can access the elements of a tuple using pattern matching.

-- Pattern matching to extract elements
age :: (Int, String) -> Int
age (a, _) = a

name :: (Int, String) -> String
name (_, n) = n

-- Using the functions
personAge = age person  -- 25
personName = name person  -- "Alice"

Common Tuple Functions

Haskell provides some built-in functions to work with tuples, especially pairs (2-tuples):

  • fst: Returns the first element of a pair.
  • snd: Returns the second element of a pair.
pair = (10, "Hello")

firstElementOfPair = fst pair  -- 10
secondElementOfPair = snd pair  -- "Hello"

Practical Exercises

Exercise 1: List Operations

Write a function sumOfSquares that takes a list of integers and returns the sum of their squares.

sumOfSquares :: [Int] -> Int
sumOfSquares xs = sum [x * x | x <- xs]

Exercise 2: Tuple Operations

Write a function swap that takes a pair and swaps its elements.

swap :: (a, b) -> (b, a)
swap (x, y) = (y, x)

Exercise 3: Combining Lists and Tuples

Write a function pairWithIndex that takes a list and returns a list of tuples, where each tuple contains an element from the list and its index.

pairWithIndex :: [a] -> [(a, Int)]
pairWithIndex xs = zip xs [0..]

Solutions

Solution 1: List Operations

sumOfSquares :: [Int] -> Int
sumOfSquares xs = sum [x * x | x <- xs]

-- Example usage
-- sumOfSquares [1, 2, 3, 4] should return 30

Solution 2: Tuple Operations

swap :: (a, b) -> (b, a)
swap (x, y) = (y, x)

-- Example usage
-- swap (1, "Hello") should return ("Hello", 1)

Solution 3: Combining Lists and Tuples

pairWithIndex :: [a] -> [(a, Int)]
pairWithIndex xs = zip xs [0..]

-- Example usage
-- pairWithIndex ["a", "b", "c"] should return [("a", 0), ("b", 1), ("c", 2)]

Conclusion

In this section, we covered the basics of lists and tuples in Haskell. We learned how to create and manipulate lists, perform common operations, and use tuples to group different types of data. These data structures are fundamental in Haskell programming and will be used extensively in subsequent modules.

© Copyright 2024. All rights reserved