У меня есть следующий код, который использует конфигурацию Reader
для конфигурации, а также должен иметь дело с IO[Option[String]]
, и я получил код, который является этапом в моей функции encode
.
Как я могу сформулировать трансформатор монады для Reader
и OptionT
, чтобы избежать уродливых вложенных for
понятий в моей функции encode
?
def encode(fileName: String): Reader[Config, IO[Unit]] = for {
ffmpegWrapper <- findFfmpegWrapper
ffmpegBin <- findFfmpeg
} yield (for {
w <- ffmpegWrapper
b <- ffmpegBin
stream <- callFfmpeg(getCommand(w, b, fileName)).liftM[OptionT]
} yield stream) map (_ foreach (println)) getOrElse Unit.box {}
def getCommand(ffmpegWrapper: String, ffmpegBin: String,
videoFile: String) = s"$ffmpegWrapper $ffmpegBin $videoFile '-vcodec libx264 -s 1024x576' /tmp/out.mp4"
def callFfmpeg(command: String): IO[Stream[String]] = IO {
Process(command).lines_!
}
def findFile(path:List[String]): OptionT[IO,String] = OptionT[IO,String](IO{path.find(new File(_).exists)})
def findFfmpeg:Reader[Config, OptionT[IO,String]] = Reader {c=>findFile(c.ffmpegLocations)}
def findFfmpegWrapper:Reader[Config, OptionT[IO,String]] = Reader {c=>findFile(c.ffmpegWrapperLocations)}
Благодарственные!