Skip to content
This repository has been archived by the owner on Mar 29, 2021. It is now read-only.

Default implicit instance for Console[IO] #1

Closed
EnverOsmanov opened this issue Aug 23, 2018 · 9 comments
Closed

Default implicit instance for Console[IO] #1

EnverOsmanov opened this issue Aug 23, 2018 · 9 comments

Comments

@EnverOsmanov
Copy link

EnverOsmanov commented Aug 23, 2018

Maybe make Console.io object implicit?

implicit object io extends SyncConsole[IO]
@gvolpe
Copy link
Member

gvolpe commented Aug 28, 2018

Not sure what's the benefit other than saving two characters ._?

Haven't seen many people using implicit objects for similar use cases, for example http4s also uses a similar approach to import a particular instance: import org.http4s.client.dsl.io._ See source

@EnverOsmanov
Copy link
Author

EnverOsmanov commented Aug 28, 2018

I think it's needed for final tagless.
Let's take the example from the guide. It doesn't work like that:

import cats.effect.IO
import cats.effect.Console

myProgram[IO]

and works that way:

import cats.effect.IO
import cats.effect.Console

implicit val ConsoleIO = Console.io
myProgram[IO]

@gvolpe
Copy link
Member

gvolpe commented Aug 28, 2018

I don't think that's related to final tagless @EnverOsmanov

You can get an implicit instance of Console[IO] by just importing import cats.effect.Console.io._ as shown in the guide.

@EnverOsmanov
Copy link
Author

Have you tried running (or compile) myProgram[IO] with import cats.effect.Console.io._? It doesn't work for me.

@gvolpe
Copy link
Member

gvolpe commented Aug 28, 2018

I don't really know what myProgram[IO] is, can you share the code?

@EnverOsmanov
Copy link
Author

EnverOsmanov commented Aug 28, 2018

It is from the guide.
Ok, I'll share the code too:

object App {

  import Guide.myProgram
  import cats.effect.IO
  import cats.effect.Console.io._

  def main(args: Array[String]): Unit = {
    myProgram[IO].unsafeRunSync()
  }

}

object Guide {
  import cats.Monad
  import cats.effect.Console
  import cats.syntax.flatMap._
  import cats.syntax.functor._

  def myProgram[F[_]: Monad](implicit C: Console[F]): F[Unit] =
    for {
      _ <- C.putStrLn("Please enter your name: ")
      n <- C.readLn
      _ <- if (n.nonEmpty) C.putStrLn(s"Hello $n!")
      else C.putError("Name is empty!")
    } yield ()
}

@gvolpe
Copy link
Member

gvolpe commented Aug 28, 2018

That's right. In the guide the program that uses IO doesn't abstract over the effect.

In order to get your program working you need an implicit instance of Console[IO], for example:

object App {

  import Guide.myProgram
  import cats.effect.IO

  implicit val consoleIO: Console[IO] = new SyncConsole[IO] // or Console.io'

  def main(args: Array[String]): Unit = {
    myProgram[IO].unsafeRunSync()
  }

}

@EnverOsmanov
Copy link
Author

Ok. I just thought if there is a default implicit Monad[IO], would be nice to have default implicit Console[IO]. Thanks for the library :) .

@gvolpe
Copy link
Member

gvolpe commented Aug 28, 2018

Not really. you can look here there is a default instance for any F[_]: Sync] but it is not available implicitly to avoid conflicts.

You can also look more at the history and arguments against providing a default implicit instance here since it was an original PR of cats-effect:

Thanks 😃

gvolpe added a commit that referenced this issue Sep 18, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants