3
votes

I'm trying to learn Scalaz with a toy project of mine, I used monads in Haskell and now I want to learn how to use them in Scala with Scalaz.

The big question is, how does one use the IO() Monad in the Scala's main method?

In Haskell, the main function is of type IO() and in Scala it is of type ().

The solution I found so far was to create another function foo of type IO() and in the main method call foo.unsafePerformIO(). But this makes me cringe.

What could be a solution?

2
There's no point and the exercise would be futile - Scala is an impure functional language. Scala is not Haskell and Haskell is not Scala.M.K.

2 Answers

7
votes

Scalaz provides a SafeApp trait that allows you to replace Scala's side-effectful main method with a wrapper that looks more like Haskell's main:

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

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

Now MyMain can be used like any other JVM class with a static main.

I don't personally use SafeApp much, but it's there if you want to avoid calling unsafePerformIO by hand.

0
votes

Scala's native main method is meant to be side effectful; calling unsafePerformIO in it is completely safe.

In fact, considering most Scala projects aren't 100% pure/Scalaz code, this approach is probably the most idiomatic one. Someone might have provided an "elegance" wrapper for it, but it wouldn't add any value besides cosmetics. And, again, most of the time you'd be embedding a Scalaz IO action inside a more mainstream, non-pure and possibly even non-functional Scala code anyway.

Furthermore, in general, and even in Haskell, the unsafe functions are typically just makeSureYouKnowWhatYoureDoing functions.