Ich habe Probleme mit dem Verständnis von Monad Stacks und Monade-Transformatoren mit Scalaz7
. Ich fühle, dass ich der Antwort ziemlich nahe bin, aber ich komme einfach nicht um einen bestimmten Schritt herum.Wie ich zwischen Monad-Stacks mit Transformatoren in scalaz konvertieren 7
Der folgende Code sieht auf der Festplatte für eine ffmpeg
Binärdatei, dann erstellt einen ausführbaren Befehl ausgeführt werden, führt dann diesen Befehl und dann etwas Triviales mit der Ausgabe.
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")})
}
}
Der Code wird durch das Ausführen
Encoder.encode("/path/to/video.mp4").unsafePerformIO
Dieser Code funktioniert, aber Sie werden feststellen, dass callFfmpeg
‚s Art Signatur ist IO[Option[Stream[String]]]
statt IO[Stream[String]]
gestartet. Ich musste es ändern, um es zur Überprüfung zu bekommen, aber wirklich, da alle callFfmpeg
heißt, führen Sie einen Prozess, der eine Stream
zurückgibt es Typ-Signatur sollte IO[Stream[String]]
sein.
Meine Frage ist, angesichts der Tatsache, dass ich callFfmpeg
IO[Option[String]]
anrufen, wie komme ich zu IO[Option[Stream[String]]]
?
Warum nicht 'findFfmpeg' eine einfache, alte 'IO [Option [String]]' Aktion zurückgeben und dann in diese umwandeln? –