首页 文章

Scala和Haskell中更高的键控类型

提问于
浏览
5

Data.Foldable显示以下代数数据类型:

data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a)

kind* -> * . 它需要 a 类型 .

Prelude> :k Tree
Tree :: * -> *

现在让我们看看来自Functional Programming in Scala的Scala的 trait Foldable[_] ,"higher-kinded type":

trait Foldable[F[_]] {
  def foldRight[A,B](as: F[A])(z: B)(f: (A,B) => B): B
  ...
}

这本优秀的书说:

就像值和函数具有类型,类型和类型构造函数一样 . Scala使用种类来跟踪类型构造函数采用的类型参数的数量,...

EDIT

指定 trait Foldable[F[_]] 时, F[_] 是否始终指示较高的类型?是否有可能 F[_] 是其他什么?可能是一种类型 - F[A]

3 回答

  • 3

    Scala中的 F[_] 代表Haskell中的 * -> * :这是一种"receives"具体类型(Scala中的 _ 和Haskell中的第一个 * )并返回一个新的具体类型( F[A] 用于某些具体类型 A 和具体"container" F 在斯卡拉) .

    所以,是的, F[_] 代表一些更高的kinded类型,如 List[_]Option[_] . 在像 trait Foldable[A,F[A]] 这样的scala中定义遍历是没有用的,因为我们会说 Foldable 需要定义特定的东西被折叠( A ) .

  • 2

    你没有问过很多问题,但是如果你想要一个大概的想法:是的,这两种语言的"kind"系统都是他们自己的类型系统的类型系统 . * 类型不是通配符,而是特殊类型的原子; * 是"concrete types"的类型,如 String[String]Tree String .

    反过来有 []Tree (见区别?)的东西 * -> * ;这是"singly-parametrized types"的类型,它采用具体类型并生成另一种具体类型 .

    最后一个例子:有一些名为"monad transformers"的东西,如 MaybeT ,它采用像 IO 这样的monad,并生成另一个monad,如 IO . Maybe (如果你原谅我们一般不承认使用函数组合运算符) . 那是什么类型的?为什么, (* -> *) -> * -> * 当然:monad有点 * -> * 所以我们采用其中一种类型并将其转换为另一种类型 .

    我不能在Scala语法方面有如此多的专业知识,但在Internet上我们在Scala中看到了monad变换器特性的定义:

    trait MonadTrans[F[_[_], _]] {
      def lift[G[_] : Monad, A](a: G[A]): F[G, A]
    }
    

    所以我认为你的猜测大多是正确的(括号表示一个依赖类型) .

    拥有这些东西的类型理论可以保证你永远不会把 IO IO 这样的东西写成具体的类型,或者 MaybeT String .

  • 5

    F[_] 在该上下文中,即作为类或方法的类型参数,总是意味着更高级的类型,也就是类型构造函数 . 您也可以将其写为 F[A] ,但通常只有在您重复使用 A 来表达约束时才会这样做,例如 trait Something[F[A] <: Iterable[A]] .

    正如书中所说,这种类型限制了可以放置的东西(类型或类型构造函数) . 您可以拥有 Foldable[List]Foldable[Option] ,因为这些是1参数类型构造函数,但您不能拥有 Foldable[String]Foldable[Either] . 同样,你不能拥有 Foldable[List[Int]] ,因为 List[Int] 是一个普通的类型,如 String (即善良 * ) . 并且您可以为 T[A] = Either[String, A] 类型设置折叠,因为这是一个1参数类型,也就是1参数类型构造函数,也就是类型 * -> * ,尽管您必须使用有点难以理解的语法 Foldable[({type T[A]=Either[String, A]})#T] 来编写它 . 并且您可以看到只有为具有正确"shape"的"types"(类型构造函数) F 实现给定 foldRight 才有可能;如果 FInt ,那么 F[A] 会是什么?

    F[_] 的不同scala用法表示存在类型, F[A] forSome { type A } ;尽量不要对此感到困惑,他们没有发现 .

相关问题