当我进入 fs2 流操作的实现时,我经常在那里看到fromFreeC
和Algebra
使用。
究竟fromFreeC
和Algebra
做什么?为什么以及何时需要它们?
这是一个示例,一个 fs2 流操作eval
,它评估效果并返回一个有效的流。
def eval[F[_], O](fo: F[O]): Stream[F, O] =
fromFreeC(Algebra.eval(fo).flatMap(Algebra.output1))
当我进入 fs2 流操作的实现时,我经常在那里看到fromFreeC
和Algebra
使用。
究竟fromFreeC
和Algebra
做什么?为什么以及何时需要它们?
这是一个示例,一个 fs2 流操作eval
,它评估效果并返回一个有效的流。
def eval[F[_], O](fo: F[O]): Stream[F, O] =
fromFreeC(Algebra.eval(fo).flatMap(Algebra.output1))
在 version 2.1.0
、 classes Pull
、Stream
和的源代码中,FreeC
定义如下:
class FreeC[F[_], +O, +R]
class Pull[+F[_], +O, +R](free: FreeC[Nothing, O, R])
class Stream[+F[_], +O](free: FreeC[Nothing, O, Unit])
关键问题是Stream
和在参数上Pull
是协变F[_]
的,而FreeC
是不变的。因此,您不能将F
参数应用Stream
或Pull
直接应用到FreeC
包装值的类型。为了弥补这一点,我们在这些字段中Nothing
用作参数,并在 a和 a之间应用 use 转换,然后再返回。FreeC
free
asInstanceOf
FreeC[Nothing, O, Unit]
FreeC[F O, Unit]
然而,在这个拉取请求中,我们使类FreeC
协变,F[_]
就像Stream
and一样Pull
,所以我们可以定义:
class FreeC[+F[_], +O, +R]
class Pull[+F[_], +O, +R] (free: FreeC[F, O, R])
class Stream[+F[_], +O] (free: FreeC[F O, Unit])
因此,该fromFreeC
功能被删除。这包含在 release 中2.2.0
。
的使用Nothing
利用了 Scala-2 类型系统的特性:两者Any
和Nothing
都是多类类型,因此它们可以用作 , , 等形式的类型参数的A
实F[_]
参A[_[_]]
。