首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在scalaz 7中使用转换器在monad堆栈之间进行转换

如何在scalaz 7中使用转换器在monad堆栈之间进行转换
EN

Stack Overflow用户
提问于 2013-05-21 05:06:53
回答 1查看 407关注 0票数 6

我正在努力用Scalaz7理解monad堆栈和monad转换器。我觉得我离答案已经很近了,但我就是想不通一个特别的步骤。

下面的代码在磁盘上查找ffmpeg二进制文件,然后创建一个要运行的可执行命令,然后执行该命令,然后对输出做一些微不足道的事情。

代码语言:javascript
复制
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")})
  }
}

通过运行以下命令启动代码

代码语言:javascript
复制
Encoder.encode("/path/to/video.mp4").unsafePerformIO

这段代码可以工作,但是你会注意到callFfmpeg的类型签名是IO[Option[Stream[String]]]而不是IO[Stream[String]]。我不得不把它改成这样才能让它进行类型检查,但实际上因为callFfmpeg所做的就是调用执行一个返回Stream的进程,所以它的类型签名应该是IO[Stream[String]]

我的问题是,在我调用callFfmpeg的时候,我正在处理IO[Option[String]],我怎样才能到达IO[Option[Stream[String]]]

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-22 03:25:20

所以我已经设法通过使用liftM[OptionT]来转换类型。

所以我的callFfmpeg函数可以变成:

代码语言:javascript
复制
def callFfmpeg(command: String): IO[Stream[String]] = IO {
    Process(command).lines_!
}

我的getStream函数现在变成了:

代码语言:javascript
复制
def getStream(fileName: String): OptionT[IO, Stream[String]] = {
    val optionalCommand: OptionT[IO, String] = findFfmpeg map {
        getCommand(_, fileName)
    }
    optionalCommand >>= {
        command => callFfmpeg(command).liftM[OptionT]
    }
}

这使得从IO[Stream[String]]IO[Option[Stream[String]]]的转换成为可能,而这正是我想要的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16658428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档