Mam problemy ze zrozumieniem stosów Monady i transformatorów Monady z Scalaz7
. Czuję, że jestem całkiem blisko odpowiedzi, ale nie mogę pojąć się konkretnym krokiem.Jak przekonwertować stosy monad z transformatorami w skalażu 7
Następujący kod wygląda na dysku dla pliku binarnego ffmpeg
, a następnie tworzy polecenie do wykonania, a następnie wykonuje to polecenie, a następnie robi coś trywialnego z danymi wyjściowymi.
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")})
}
}
Kod jest skopany przez uruchomienie
Encoder.encode("/path/to/video.mp4").unsafePerformIO
Ten kod działa, ale można zauważyć, że callFfmpeg
„s typ podpis jest IO[Option[Stream[String]]]
zamiast IO[Stream[String]]
. Musiałem to zmienić, aby uzyskać sprawdzenie typu, ale tak naprawdę, ponieważ wszystkie callFfmpeg
to wywołanie procesu, który zwraca Stream
jego podpis typu powinien być IO[Stream[String]]
.
Moje pytanie brzmi, biorąc pod uwagę, że w czasie kiedy dzwonię pod numer callFfmpeg
mam do czynienia z IO[Option[String]]
jak dostać się do IO[Option[Stream[String]]]
?
Dlaczego 'findFfmpeg' nie powróci do zwykłej akcji' IO [Option [String]] ', a następnie odwzoruje w niej? –