Skip to content

Instantly share code, notes, and snippets.

@tomwadeson
Created June 18, 2019 16:06
Show Gist options
  • Save tomwadeson/632b8d44341c67f7e06331613545b890 to your computer and use it in GitHub Desktop.
Save tomwadeson/632b8d44341c67f7e06331613545b890 to your computer and use it in GitHub Desktop.
trait Console[F[_]] {
  def readLine: F[String]
  def printLine(s: String): F[Unit]
}
// I know that all this function can do is call `readLine`.
// What's more, it can only do it exactly (usefully) once.
// Anything else would be a reason to talk
def foo[F[_] : Console]: F[String] = ???
// This could call `readLine` *or* `printLine`
// It can still only do it exactly (usefully) once.
// I've no guarantee that the `F[String]` I get back is from from `readLine`
// Anything else would be a reason to talk
def foo[F[_] : Functor : Console]: F[String] = ???
// This could call `readLine` or `printLine` many times
// It could also now call `readLine` or `printLine` zero times
// It's not able to respond to user input, e.g. greeting a user by their name
// Anything else would be a reason to talk
def foo[F[_] : Applicative : Console]: F[String] = ???
// This can do everything that the previous can do and more...
// Now we can respond to user input
def foo[F[_] : Monad : Console]: F[String] = ???

Compare to:

trait Console {
  def readLine: IO[String]
  def println(s: String): IO[Unit]
}

// What can I say about what this does? Or doesn't do? Or *shouldn't* do?
// What would the implementation need to do to provoke a conversation?
def foo(c: Console): IO[String] = ???
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment