2.

val mapFun: (String, Char => Char) => String =
  (str, fun) => str.foldLeft("")( (acc, el) =>
    acc + fun(el)
  )

3.

val flatMapFun: (String, Char => String) => String =
  (str, fun) => str.foldLeft("")( (acc, el) =>
    acc + fun(el)
  )

4.

val foreachFun: (String, Char => Unit) => Unit =
  (str, fun) => str.foldLeft(())( (_, el) =>
    fun(el)
  )

5.

val existsFun: (String, Char => Boolean) => Boolean =
  (str, fun) => str.foldLeft(false)( (acc, el) =>
    fun(el) || acc
  )

6.

val filterNotFun: (String, Char => Boolean) => String =
  (str, fun) => str.foldLeft("")( (acc, el) =>
    if (fun(el))
      acc
    else
      acc + el
  )

7.

val distinctByFun: (String, Char => Char) => String =
  (str, fun) => str.foldLeft("")( (acc, el) => {
    val newEl = fun(el)
    if (acc.contains(newEl))
      acc
    else
      acc + newEl
  })

8.

val forallFun: (String, Char => Boolean) => Boolean =
  (str, fun) => str.foldLeft(true)( (acc, el) =>
    fun(el) && acc
  )

9.

val countFun: (String, Char => Boolean) => Int =
  (str, fun) => str.foldLeft(0)( (acc, el) =>
    if (fun(el)) acc + 1
    else acc
  )

10.

val takeWhileFun: (String, Char => Boolean) => String =
  (str, fun) => str.foldLeft(("", false))( (acc, el) => {
    val (res, isEnd) = acc
    if (isEnd)
      (res, isEnd)
    else
      if (fun(el))
        (res + el, false)
      else
        (res, true)
  })._1

11.

val dropWhileFun: (String, Char => Boolean) => String =
  (str, fun) => str.foldLeft(("", false))( (acc, el) => {
    val (res, isEnd) = acc
    if (isEnd)
      (res + el, isEnd)
    else
      if (fun(el))
        (res, false)
      else
        (res + el, true)
  })._1

12.

val filterGen: String => (Char => Boolean) =
  str =>
    if (str.length > 3)
      char => char.isDigit
    else
      char => char.isLetter