In this section, we will explore two important type classes in Haskell: Functor
and Foldable
. These type classes provide powerful abstractions for working with data structures in a functional way.
Functor
What is a Functor?
A Functor
is a type class that represents types that can be mapped over. In other words, a Functor
is a container that you can apply a function to each element inside it.
Functor Type Class
The Functor
type class is defined as follows:
fmap
is a function that takes a function(a -> b)
and a functorf a
, and returns a new functorf b
with the function applied to each element.
Example: Functor Instance for List
Lists are a common example of a Functor
. Here’s how the Functor
instance for lists is defined:
Using fmap
Here’s an example of using fmap
with a list:
-- Define a function to double a number double :: Int -> Int double x = x * 2 -- Use fmap to apply the function to each element in the list doubledList = fmap double [1, 2, 3, 4, 5] -- Result: [2, 4, 6, 8, 10]
Practical Exercise: Functor
Exercise: Implement a Functor
instance for a custom data type Maybe
.
data Maybe a = Nothing | Just a instance Functor Maybe where fmap _ Nothing = Nothing fmap f (Just x) = Just (f x)
Solution:
-- Define a function to increment a number increment :: Int -> Int increment x = x + 1 -- Use fmap to apply the function to a Maybe value incrementedMaybe = fmap increment (Just 5) -- Result: Just 6 incrementedNothing = fmap increment Nothing -- Result: Nothing
Foldable
What is Foldable?
Foldable
is a type class that represents data structures that can be folded to a summary value. Folding is a way to reduce a data structure to a single value by iteratively applying a function.
Foldable Type Class
The Foldable
type class is defined as follows:
foldr
is a function that takes a binary function(a -> b -> b)
, an initial accumulator valueb
, and a foldable structuret a
, and reduces it to a single valueb
.
Example: Foldable Instance for List
Lists are also a common example of a Foldable
. Here’s how the Foldable
instance for lists is defined:
Using foldr
Here’s an example of using foldr
with a list:
-- Define a function to sum two numbers sum' :: Int -> Int -> Int sum' x y = x + y -- Use foldr to sum all elements in the list sumList = foldr sum' 0 [1, 2, 3, 4, 5] -- Result: 15
Practical Exercise: Foldable
Exercise: Implement a Foldable
instance for a custom data type Tree
.
data Tree a = Empty | Node a (Tree a) (Tree a) instance Foldable Tree where foldr _ z Empty = z foldr f z (Node x left right) = foldr f (f x (foldr f z right)) left
Solution:
-- Define a function to multiply two numbers multiply :: Int -> Int -> Int multiply x y = x * y -- Create a sample tree sampleTree = Node 1 (Node 2 Empty Empty) (Node 3 Empty Empty) -- Use foldr to multiply all elements in the tree productTree = foldr multiply 1 sampleTree -- Result: 6
Summary
In this section, we covered the Functor
and Foldable
type classes in Haskell. We learned how to use fmap
to apply functions to elements inside functors and how to use foldr
to reduce foldable structures to a single value. We also implemented custom instances for Maybe
and Tree
data types to reinforce these concepts.
Next, we will delve into more advanced functional programming concepts, such as Monads, in the following module.
Haskell Programming Course
Module 1: Introduction to Haskell
- What is Haskell?
- Setting Up the Haskell Environment
- Basic Syntax and Hello World
- Haskell REPL (GHCi)