Mam następujący kod, który używa monady Reader
do konfiguracji, a także ma do czynienia z IO[Option[String]]
i skończyłem z kodem, że kroki schodowe w mojej funkcji encode
.Jak uniknąć schodkowych z Monad Transformers w scala?
Jak mogę sformułować transformator monada dla Reader
i OptionT
aby uniknąć brzydkich zagnieżdżone for
listowych w moim encode
funkcji?
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)}
Dziękuję!
Byłem w trakcie pisania prawie identycznej odpowiedzi, kiedy pojawiło się twoje. Zmieniłem górną część Twojej odpowiedzi na coś, co było w moim, ale nie w twoim o wyświetleniu aliasu Reader = ReaderT, proszę go usunąć, jeśli uważasz, że nie dodaje się do Twojej odpowiedzi :) – stew
@stew: Podziękowania ! Właśnie dodałem link do źródła, o którym wspomniałeś. –
Travis i @stew są niezwykle pomocne! Wypróbuj to teraz. – cwmyers