我通过编写简单的应用程序来学习FP。现在我接近效果monad(cats.effect.IO
/ scalaz.IO
并不重要)。我有两个功能:
def open(path: String): IO[InputStream] = IO {
new FileInputStream(new File(path))
}
def read(is: InputStream): IO[Option[Array[Byte]]] = IO {
val buffer = new Array[Byte](4096)
val bytesRead = is.read(buffer)
if (bytesRead != -1) {
val newBuffer = new Array[Byte](bytesRead)
System.arraycopy(buffer, 0, newBuffer, 0, bytesRead)
print(new String(buffer))
Some(newBuffer)
}
else
None
}
我可以将它们组合成一个流,如下所示
import cats.effect.IO
import fs2.Stream
object App {
def main(args: Array[String]): Unit = logic.unsafeRunSync()
def logic: IO[Unit] = for {
is <- open("/tmp/prompthooks.py")
_ <- fs2.Stream.eval(read(is)).repeat.unNoneTerminate.compile.drain
} yield ()
}
它工作正常。但问题是它是否都是在纯FP中实现的。我对此感到怀疑,因为def read(is: InputStream): IO[Option[Array[Byte]]
接受了流并尝试从中读取。是的,它会暂停副作用但在val io = read(is)
中是有状态的(如果我们执行unsafeRunSync
两次,我们会得到不同的结果。