6

Scala 3 原生 FunctionK

 3 years ago
source link: https://blog.oyanglul.us/scala/dotty/functionk
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Scala 3 原生 FunctionK

Scala 3 原生 FunctionK

Table of Contents

中文 | English


可以跑的源码在这里 👉 https://github.com/jcouyang/meow


Scala 2

没有 FunctionK 所以我们需要使用 Cats 的 FunctionK 来做一些事情. 当 FunctionK[F, G] 的 F 和 G 都是 Functor 时, FunctionK 是 F ~> G 的自然变换.

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

至于为什么不能直接用普通类型为 Option[A] => List[A] 的函数而要用 FunctionK 呢? 请看 Rank-N types.

Scala 3

在 Dotty 中, 已经实现了 Rank N Types, 叫 Polymorphic function types, 就可以很轻松的定义出 ~>:

// kind * -> *
// FunctionK (* -> *) -> (* -> *)

type ~>[F[_],G[_]] = [A] => F[A] => G[A]

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)
    )
  }
}

不需任何cats, 是可以完美编译运行的.

不信? 可以自己在 scastie 上试试: https://scastie.scala-lang.org/jcouyang/W5jIXajVTU64g8KZe8V7Kw/9

Footnotes:

1

当 FunctionK[F, G] 的 F 和 G 都是 Functor 时, FunctionK 是 F ~> G 的自然变换.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK