モナドスタックとモナドトランスフォーマーを理解するのに苦労していScalaz7
ます。私は答えにかなり近づいていると感じていますが、特定のステップに頭を悩ませることはできません.
次のコードは、ディスク上でffmpeg
バイナリを検索し、実行する実行可能なコマンドを作成し、そのコマンドを実行して、出力に対して簡単な処理を行います。
object Encoder {
def findFfmpeg: OptionT[IO, String] = {
OptionT[IO, String](IO {
List("/usr/local/bin/ffmpeg", "/usr/bin/ffmpeg").find {
new File(_).exists
}
}
)
}
def getCommand(ffmpegBin: String,
videoFile: String) = s"$ffmpegBin $videoFile '-vcodec libx264 -s 1024x576' /tmp/out.mp4"
def callFfmpeg(command: String): IO[Option[Stream[String]]] = IO {
Some(Process(command).lines_!)
}
def getStream(fileName: String): OptionT[IO, Stream[String]] = {
val optionalCommand: OptionT[IO, String] = findFfmpeg map {
getCommand(_, fileName)
}
optionalCommand >>= {
command => OptionT[IO, Stream[String]](callFfmpeg(command))
}
}
def encode(fileName: String): IO[Unit] = {
getStream(fileName) map {
a: Stream[String] =>
a map {
_.length
} foreach (println)
} getOrElse (Unit.box {println("nothing")})
}
}
コードは実行によって開始されます
Encoder.encode("/path/to/video.mp4").unsafePerformIO
callFfmpeg
このコードは機能しますが、の型シグネチャがIO[Option[Stream[String]]]
ではなく であることに気付くでしょうIO[Stream[String]]
。型チェックを行うには、それを変更する必要がありましたが、実際には、型シグネチャcallFfmpeg
を返すプロセスを実行するだけなので、 .Stream
IO[Stream[String]]
私の質問は、私が電話をかけたときに、どうやって にたどり着くかをcallFfmpeg
扱っていることを考えると、IO[Option[String]]
IO[Option[Stream[String]]]