6

モナドスタックとモナドトランスフォーマーを理解するのに苦労していScalaz7ます。私は答えにかなり近づいていると感じていますが、特定のステップに頭を悩ませることはできません.

次のコードは、ディスク上でffmpegバイナリを検索し、実行する実行可能なコマンドを作成し、そのコマンドを実行して、出力に対して簡単な処理を行います。

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")})
  }
}

コードは実行によって開始されます

Encoder.encode("/path/to/video.mp4").unsafePerformIO

callFfmpegこのコードは機能しますが、の型シグネチャがIO[Option[Stream[String]]]ではなく であることに気付くでしょうIO[Stream[String]]。型チェックを行うには、それを変更する必要がありましたが、実際には、型シグネチャcallFfmpegを返すプロセスを実行するだけなので、 .StreamIO[Stream[String]]

私の質問は、私が電話をかけたときに、どうやって にたどり着くかをcallFfmpeg扱っていることを考えると、IO[Option[String]]IO[Option[Stream[String]]]

4

1 に答える 1