Sto lottando con la comprensione di monad stack e trasformatori monad con Scalaz7
. Sento che sono abbastanza vicino alla risposta, ma non riesco a capire la situazione.Come convertire tra stack monad con trasformatori in scalaz 7
Il seguente codice cerca sul disco un binario ffmpeg
, quindi crea un comando eseguibile da eseguire, quindi esegue quel comando e quindi fa qualcosa di banale con l'output.
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")})
}
}
il codice viene dato il via eseguendo
Encoder.encode("/path/to/video.mp4").unsafePerformIO
Questo codice funziona, ma si noterà che callFfmpeg
's tipo di firma è IO[Option[Stream[String]]]
invece di IO[Stream[String]]
. Ho dovuto cambiarlo per farlo controllare il tipo, ma dal momento che tutto il callFfmpeg
fa è chiamare eseguire un processo che restituisce un Stream
la sua firma dovrebbe essere IO[Stream[String]]
.
La mia domanda è, dato che al momento chiamo callFfmpeg
ho a che fare con IO[Option[String]]
come posso arrivare a IO[Option[Stream[String]]]
?
Perché non trovare "findFfmpeg" restituisce una semplice vecchia azione "IO [Opzione [String]]' e quindi mappare in quella? –