【问题标题】:Scalaz and main methodScalaz 和 main 方法
【发布时间】:2015-09-10 06:24:27
【问题描述】:

我正在尝试通过我的一个玩具项目来学习 Scalaz,我在 Haskell 中使用过 monad,现在我想学习如何在 Scala 中通过 Scalaz 使用它们。

最大的问题是,如何在 Scala 的 main 方法中使用 IO() Monad?

在 Haskell 中,main 函数的类型为 IO(),而在 Scala 中,它的类型为 ()

到目前为止,我找到的解决方案是创建另一个 foo 类型的函数 IO() 并在 main 方法中调用 foo.unsafePerformIO()。但这让我感到畏缩。

有什么解决办法?

【问题讨论】:

  • 没有意义,而且练习也是徒劳的 - Scala 是一种不纯的函数式语言。 Scala 不是 Haskell,Haskell 也不是 Scala。

标签: scala haskell monads scalaz


【解决方案1】:

Scalaz 提供了一个 SafeApp trait,它允许您用看起来更像 Haskell 的 main 的包装器替换 Scala 的副作用 main 方法:

import scalaz._, Scalaz._, effect.{ IO, SafeApp }

object MyMain extends SafeApp {
  override def runl(args: List[String]): IO[Unit] = IO(println("hello world"))
}

现在MyMain 可以像任何其他具有静态main 的JVM 类一样使用。

我个人不经常使用SafeApp,但如果您想避免手动调用unsafePerformIO,它就在那里。

【讨论】:

  • 既然你用的不多,Travis,你干脆做:def main(args: Array[String]): Unit = ioReturningMethod.unsafePerformIO
  • 我使用的是最新的 ScalaZ 版本7.2.27,但是当我打电话给scalaz.effect.SafeApp 时,我得到object effect is not a member of package scalaz 知道为什么吗?
  • @Wonay 你有scalaz-effect作为依赖吗?
【解决方案2】:

Scala 的原生 main 方法是有副作用的;在其中调用unsafePerformIO 是完全安全的。

事实上,考虑到大多数 Scala 项目都不是 100% 纯/Scalaz 代码,这种方法可能是最惯用的方法。有人可能为它提供了一个“优雅”的包装,但除了化妆品之外,它不会增加任何价值。而且,在大多数情况下,您还是会将 Scalaz IO 操作嵌入到更主流、非纯甚至可能没有功能的 Scala 代码中。

此外,一般来说,甚至在 Haskell 中,unsafe 函数通常只是 makeSureYouKnowWhatYoureDoing 函数。

【讨论】:

  • 在 Haskell 中,存在一系列不安全因素,从安全方面的 unsafeInterleaveIO 一直到吃掉你的短裤方面的 unsafeDupablePerformIO
  • 如果您知道自己在做什么,所有这些都可以使用,对吧?
  • 毫无疑问。有些会导致比其他更多的错误,但都有其用途。
  • 我同意这里所说的一切,但是 Scalaz 中有这样一个包装器,并且使用它至少可以说是 Scalaz 惯用的(无论它值多少钱),所以这不是一个真正的答案对OP的问题。
  • (为了记录,我不会对此投反对票——我认为这是合理的信息。)
猜你喜欢
  • 2016-07-27
  • 1970-01-01
  • 2016-07-29
  • 2016-09-03
  • 2018-03-29
  • 2014-06-20
  • 2013-08-09
  • 2012-11-04
  • 2015-06-02
相关资源
最近更新 更多