## Higher Kinded Type Parameters
---
Let's recall basic type parameters:
```scala [1-3]
// type parameter `B` - accumulator
// type parameter `T` - element
def foldLeft[B, T](acc: B)(f: (B, T) => B): B = ???
```
---
This type parameters represent an abstract type
What if type parameter represented a function?
---
Scala allows such parameters:
```scala [1-5]
// type parameter `F[_]` - abstract collection
// type parameter `B` - accumulator
// type parameter `T` - element
def foldLeftCollection[F[_], B, T](collection: F[T])
(acc: B)(f: (B, T) => B): B = ???
```
---
- `F[_]` is a type constructor
- By applying `F[_]` to types `A`, `B`, `C` we will get three new types:
`F[A]`, `F[B]`, `F[C]`
---
Everything that is shaped like `F[_]` can be used as a substitution:
```scala
trait Foo[F[_]] {
def bar: F[Int]
}
val fooOption: Foo[Option] = _ => Some(1)
val fooList: Foo[List] = _ => List(1)
val fooIO: Foo[IO] = _ => IO(1)
```