Tôi có đoạn mã sau sử dụng đơn Reader
để cấu hình và cũng phải xử lý IO[Option[String]]
và tôi đã kết thúc bằng mã mà bước cầu thang trong hàm encode
của tôi.Làm thế nào để tránh cầu thang bước với Monad Transformers trong scala?
Làm cách nào tôi có thể xây dựng một biến áp đơn lẻ cho Reader
và OptionT
để tránh hàm lồng nhau xấu xí for
trong hàm encode
của tôi?
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)}
Cảm ơn!
Tôi đang trong quá trình viết lên một câu trả lời giống hệt như khi bạn xuất hiện. Tôi đã sửa đổi phần đầu câu trả lời của bạn với nội dung nào đó của tôi nhưng không phải trong của bạn về hiển thị bí danh loại Reader = ReaderT, vui lòng xóa nó nếu bạn cho rằng nó không thêm vào câu trả lời của bạn :) – stew
@stew: Cảm ơn ! Tôi vừa thêm liên kết vào nguồn bạn đã đề cập. –
Travis và @stew điều này cực kỳ hữu ích! Chỉ cần thử nó ngay bây giờ. – cwmyers