Я учу FP, написав простые приложения.И сейчас я подхожу к эффекту монады (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
дважды, мы получим другой результат.