liveBook · Manning

Fmap

As explained in Functional Design and Architecture: Examples in Haskell

fmap is the standard functor-mapping operation that applies a function to a functor's contained values while preserving its structure.

When a transformation should change contained values without changing a data structure's shape, fmap applies the function while preserving that structure. Lists, Maybe values, and other Functors can therefore share the same mapping operation. section 1.3.3 section 6.3.3

The operation generalizes familiar transformations across several containers:

  • For a list, fmap is equivalent to map: it can convert integers to strings, double them, or produce nested lists while retaining the list structure. section 6.3.3
  • For Maybe values inside a list, nested fmap traverses both layers, transforming Just contents while leaving Nothing unchanged. section 1.3.3
  • For SandwichConstructor, fmap transforms continuation results while repacking the original constructors and preserving the script shape. section 6.3.3

Mapping through nested structure

Given maybeNames = [Just "Alice", Just "Bob", Nothing], applying fmap (fmap length) produces [Just 5, Just 3, Nothing]. The outer fmap maps the list; the inner fmap maps each Maybe value. section 1.3.3

Listing 6.3 Functor instance for the free monad
instance Functor SandwichConstructor where              #1
  
  fmap f (StartNewSandwich breadType component next)    #2
    = StartNewSandwich breadType component (f . next)
  
  fmap f (AddComponent component sandwichBody next)
    = AddComponent component sandwichBody (f . next)
  
  fmap f (FinishSandwich mbBreadType sandwichBody next)
    = FinishSandwich mbBreadType sandwichBody (f . next)

Inspect a custom Functor instance that maps over continuation results without altering SandwichConstructor's constructors. section 6.3.3

How Functional Design and Architecture: Examples in Haskell covers it

How deep it goes
Defines Functor behavior, works through list and Maybe examples, and implements fmap for a custom free-monad constructor.
Examples
Uses name-length lists, nested Maybe values, integer transformations, and SandwichConstructor continuations.
What it assumes
Assumes functions and parameterized data types, while teaching the Functor idea through lists, Maybe, and a custom instance.
What you can do after
Apply transformations with fmap while preserving list, Maybe, or custom Functor structure.
How it connects
Connects Functor, list, Maybe, map, free monads, continuations, and monadic scripts.

Also explained in

Compare how 3 books explain fmap →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Functional Design and Architecture: Examples in Haskell. The section links point to the parts of the book it draws on.