Haskell Custom Functor Instances
A custom Functor instance is a Functor definition written for a new type. It tells fmap how to reach the value held inside that type.
A custom Box instance adds one to the held number
The instance unwraps the Box, adds one, and wraps the result again. The output shows Box 6.
data Box a = Box a deriving Show
instance Functor Box where
fmap f (Box x) = Box (f x)
main :: IO ()
main = print (fmap (+1) (Box 5))The same instance finds the length of a held string
The instance applies length to the held string. The output shows Box 5 for a five-letter string.
data Box a = Box a deriving Show
instance Functor Box where
fmap f (Box x) = Box (f x)
main :: IO ()
main = print (fmap length (Box "hello"))The same instance reverses a held list
The instance applies reverse to the held list. The output shows the list in reverse order inside Box.
data Box a = Box a deriving Show
instance Functor Box where
fmap f (Box x) = Box (f x)
main :: IO ()
main = print (fmap reverse (Box [1,2,3]))Example
data Box a = Box a deriving Show
instance Functor Box where
fmap f (Box x) = Box (f x)
main :: IO ()
main = do
print (fmap (+1) (Box 10))
print (fmap (*2) (fmap (+1) (Box 10)))Key points
- Box: a simple wrapper type that holds one value of any type.
- Instance: a declaration that supplies a typeclass operation for one type.
- fmap definition: the part of the instance that applies a function to the held value and wraps the result again.
- Deriving: a way to ask GHC to fill in a typeclass such as Show for a type.
- Wrapper result: fmap over Box returns a Box holding the changed value.
In this example, Box holds one number and its Functor instance is defined above main. The first line adds one to the held number. The second line adds one and then doubles the result.
Note
the instance must follow the Functor laws just like a built-in instance.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Haskell Playground
Exercise
What is fmap (+1) (Box 5) for the Box instance in this lesson?