The `Functor`

typeclass abstracts the ability to `map`

over the computational context of a type constructor.
Examples of type constructors that can implement instances of the Functor typeclass include `Option`

, `NonEmptyList`

,
`List`

and many other datatypes that include a `map`

function with the shape `fun F<B>.map(f: (A) -> B): F<B>`

where `F`

refers to `Option`

, `List`

or any other type constructor whose contents can be transformed.

Often times we find ourselves in situations where we need to transform the contents of some datatype. `Functor#map`

allows
us to safely compute over values under the assumption that they’ll be there returning the transformation encapsulated in the same context.

Consider both `Option`

and `Try`

:

`Option<A>`

allows us to model absence and has two possible states, `Some(a: A)`

if the value is not absent and `None`

to represent an empty case.

In a similar fashion `Try<A>`

may have two possible cases `Success(a: A)`

for computations that succeed and `Failure(e: Throwable)`

if they fail with an exception.

Both `Try`

and `Option`

are example datatypes that can be computed over transforming their inner results.

```
import arrow.*
import arrow.core.*
import arrow.data.*
import arrow.syntax.function.*
Try { "1".toInt() }.map { it * 2 }
Option(1).map { it * 2 }
//Some(2)
```

Both `Try`

and `Option`

include ready to use `Functor`

instances:

```
val optionFunctor = Option.functor()
```

```
val tryFunctor = Try.functor()
```

Mapping over the empty/failed cases is always safe since the `map`

operation in both Try and Option operate under the bias of those containing success values

```
import arrow.syntax.option.*
Try { "x".toInt() }.map { it * 2 }
none<Int>().map { it * 2 }
//None
```

Arrow allows abstract polymorphic code that operates over the evidence of having an instance of a typeclass available.
This enables programs that are not coupled to specific datatype implementations.
The technique demonstrated below to write polymorphic code is available for all other `Typeclasses`

beside `Functor`

.

```
import arrow.typeclasses.*
inline fun <reified F> multiplyBy2(fa: HK<F, Int>, FT: Functor<F> = functor()): HK<F, Int> =
FT.map(fa, { it * 2 })
multiplyBy2<OptionHK>(Option(1)) // Option(1)
multiplyBy2<TryHK>(Try { 1 })
//Success(value=2)
```

In the example above we’ve defined a function that can operate over any data type for which a `Functor`

instance is available.
And then we applied `multiplyBy2`

to two different datatypes for which Functor instances exist.
This technique applied to other Typeclasses allows users to describe entire programs in terms of behaviors typeclasses removing
dependencies to concrete data types and how they operate.

This technique does not enforce inheritance or any kind of subtyping relationship and is frequently known as `ad-hoc polymorphism`

and frequently used in programming languages that support Typeclasses and Higher Kinded Types.

Entire libraries and applications can be written without enforcing consumers to use the lib author provided datatypes but letting users provide their own provided there is typeclass instances for their datatypes.

Transforms the inner contents

`fun <A, B> map(fa: HK<F, A>, f: (A) -> B): HK<F, B>`

```
optionFunctor.map(Option(1), { it + 1 })
//Some(2)
```

Lift a function to the Functor context so it can be applied over values of the implementing datatype

`fun <A, B> lift(f: (A) -> B): (HK<F, A>) -> HK<F, B>`

```
val lifted = optionFunctor.lift({ n: Int -> n + 1 })
lifted(Option(1))
//Some(2)
```

For a full list of other useful combinators available in `Functor`

see the Source

Maps over any higher kinded type constructor for which a functor instance is found

```
Try { 1 }.map({ it + 1 })
//Success(value=2)
```

Lift a function into the functor context

```
import arrow.syntax.functor.*
val f = { n: Int -> n + 1 }.lift<OptionHK, Int, Int>()
f(Option(1))
//Some(2)
```

Arrow provides `FunctorLaws`

in the form of test cases for internal verification of lawful instances and third party apps creating their own Functor instances.

`Functor`

instancesArrow already provides Functor instances for most common datatypes both in Arrow and the Kotlin stdlib. Often times you may find the need to provide your own for unsupported datatypes.

You may create or automatically derive instances of functor for your own datatypes which you will be able to use in the context of abstract polymorfic code as demonstrated in the example above.

See Deriving and creating custom typeclass

The following datatypes in Arrow provide instances that adhere to the `Functor`

typeclass.

- Cofree
- Coproduct
- Coyoneda
- Either
- EitherT
- FreeApplicative
- Function1
- Ior
- Kleisli
- OptionT
- StateT
- Validated
- WriterT
- Yoneda
- Const
- Try
- Eval
- IO
- NonEmptyList
- Id
- Function0

Additionally all instances of `Applicative`

, `Monad`

and their MTL variants implement the `Functor`

typeclass directly
since they are all subtypes of `Functor`