Instantly share code, notes, and snippets.

# afsalthaj/blog.md Secret

Created June 29, 2018 06:50
Show Gist options
• Save afsalthaj/670023f4bd2606c8e1d76bfbdd393a3b to your computer and use it in GitHub Desktop.

## Invariant Functors

People tend to forget this quite often. An invariant functor or an exponential functor is:

https://gist.github.com/77923fc3b7583cf7bfc6c2b5b92fba21

## Covariant Functor

That's the famous `Functor` ! Covariant functor implements xmap by discarding `g: B => A`

https://gist.github.com/e7f0a2910c403d0cf04fcc6bb29de583

## Contravariant Functor

As expected, it discards `f: A => B` and makes use of `contramap` to implement `xmap`

https://gist.github.com/f91e1ea7e6801dc91f9b328e6a12367b

## Example for Contravariant Functor

https://gist.github.com/b658245bf47f647f02513213ce6aa719

## Usage

https://gist.github.com/67259a39c54dc7ae897a35882ff94288

## Example for covariant Functor

As expected, it is `DecodeJson`, where the type parameter in the type class comes at covariant position (method result)

https://gist.github.com/334fe6c8841721540bb719c8cdffd66f

## Note

If type parameters are at covariant position, that means the method return contains the type.

If type parameters are at contravariant position, that means the method parameters contain the type.

## When is invariant functor?

We may have types at covariant (output) or contravariant (input) position. However, we may sometime deal with both covariance and contravariance in the same type class.

Let's bring in EncodeJson and DecodeJson into one type class.

## EncodeJson and DecodeJson

https://gist.github.com/d5320b66c64ea82580495476d33a76cd

## Functor but invariant

So an individual `map` or `contramap` to upcast (or downcast) an A to B in the context of `F[_]` is not possible if `F` has types both in covariant and contravariant positions. It means, `F` has to have an invariant functor for it!