type Pipe[F[_], -I, +O] = Stream[F, I] => Stream[F, O]
我理解F[_]
、-I
、+O
。缺少的部分F
在右侧。为什么不Stream[F[_]]
? 我想左边和右边的F有不同的含义。有没有关于编写类型定义的规则的官方文档?
我检查流的类型,
scala> :kind fs2.Stream
fs2.Stream's kind is X[+F[A1],+A2]
在另一种情况下:
scala> trait Functor [F[_]] {
| def map[A,B] (fn: A=>B)(fa: F[A]): F[B]
| }
trait Functor
scala> :kind Functor
Functor's kind is X[F[A]]
为什么F[A]
没有被 F 取代?当然,我对不同的概念感到困惑,但我应该在一个地方在哪里学习它们。
我想左边和右边的F有不同的含义
更准确地说,左右两侧的下划线_
具有不同的含义。前者表示匿名类型参数,而后者表示适当的通配符类型。Scala 3的未来版本最终应该使含义相同
它还删除了用作类型参数的疣,
F[_]
表示F
是一个类型构造函数,而用作类型,F[_]
意味着它是一个 通配符(即存在)类型。在未来,F[_]
将意味着 同样的事情,无论在哪里使用
为了说明这一点,请考虑
scala> trait Foo[F[_]]
// defined trait Foo
scala> type Bar[F[_]] = Foo[F[_]]
1 |type Bar[F[_]] = Foo[F[_]]
| ^^^^
| Type argument F[?] does not have the same kind as its bound [_$1]
scala> type Bar[F[_]] = Foo[F[?]]
1 |type Bar[F[_]] = Foo[F[?]]
| ^^^^
| Type argument F[?] does not have the same kind as its bound [_$1]
scala> type Bar[F[_]] = Foo[([x] =>> F[x])[?]]
1 |type Bar[F[_]] = Foo[([x] =>> F[x])[?]]
| ^^^^^^^^^^^^^^^^^
| Type argument F[Any] does not have the same kind as its bound [_$1]
请注意右侧的下划线等效于
([x] =>> F[x])[?]
其中 lambda[x] =>> F[x]
类型应用于正确的类型?
,从而产生正确的类型([x] =>> F[x])[?]
。但是Foo
是高阶类型构造函数,它期望另一个类型构造函数作为参数,而不是正确的类型。因此,以下作品
scala> type Bar[F[_]] = Foo[F]
// defined alias type Bar[F] = Foo[F]
scala> type Bar[F[_]] = Foo[[x] =>> F[x]]
// defined alias type Bar[F] = Foo[F]
请注意如何将 lambda[x] =>> F[x]
类型传递给"未应用"Foo
。