# FunctionK in Scala 3

I'm recently migrating some libs and projects to Scala 3, I guess it would be very helpful to me or anyone interested to learn some new functional programming features that Scala 3 is bringing to us.

## Scala 2

Last section we've seen the usable of FunctionK and Id in Cats when we were trying to implement rank N types in Scala 2.

But the actual usable of FunctionK is like:

import cats.~> def tupledOptionToList[B,C](a: (Option[B], Option[C]), fnk: Option ~> List): (List[B], List[C]) = (fnk(a._1), fnk(a._2))

Same reason as rank n types, normal function `Option[A] => List[A]`

won't work since `A`

should not be in the same rank with `B`

and `C`

.

So `Option ~> List~`

When `F`

and `G`

are `Functor`

, `FunctionK[F, G]`

is the natural transformation from `F`

to `G`

, noted `F ~> G`

.
hide the `A`

type, means the function only map Kind to other Kind, and leave what ever type `A`

not changed,
which is also why is called FunctionK(K for Kind).

## Scala 3

While in Scala 3, since we have Rank N Types, a.k.a Polymorphic function types, it is very easy to implement `~>`

.

Basically you don't even need to implement, just a type alias will do:

// kind: * -> * // FunctionK: (* -> *) -> (* -> *) type ~>[F[?],G[?]] = [A] => F[A] => G[A]

Use the `~>`

in infix position, you will get exactly same thing Cats FunctionK does:

object Main { // rank 2 type (forall a. Option a -> List a) val optionToList: Option ~> List = [A] => (a: Option[A]) => a.toList // forall b c. (Option b, Option c) -> (forall a. Option a -> List a) -> (List b, List c) def tupledOptionToList[B,C](a: (Option[B], Option[C]), fnk: Option ~> List): (List[B], List[C]) = (fnk(a._1), fnk(a._2)) def main(args: Array[String]): Unit = { println( tupledOptionToList((Some(1), Some("2")), optionToList) ) } }

No Cats needed, even better, it's much easier to define a functionK too:

// Cats val optionToList: Option ~> List = new (Option ~> List) { def apply(a: Option[A]): List[A] = a.toList } // Scala 3 val optionToList: Option ~> List = [A] => (a: Option[A]) => a.toList

Try the above examples online: https://scastie.scala-lang.org/jcouyang/W5jIXajVTU64g8KZe8V7Kw/9

Or clone and run it locally: https://github.com/jcouyang/meow

## Footnotes:

^{1}

When `F`

and `G`

are `Functor`

, `FunctionK[F, G]`

is the natural transformation from `F`

to `G`

, noted `F ~> G`

.