Join GitHub today
Provides effect type agnostic Console #256
I think many of us were interested in at least having a
In this PR a
Also, I used
Okay so what about defining a default instance on
We can also have a default
You can't have a
@@ Coverage Diff @@ ## master #256 +/- ## ========================================== - Coverage 88.97% 88.47% -0.51% ========================================== Files 63 64 +1 Lines 1624 1631 +7 Branches 172 178 +6 ========================================== - Hits 1445 1443 -2 - Misses 179 188 +9
@oleg-py I actually agree in general, it's just that
Anyway, it's really not a hill I'm willing to die on, just that I've rewritten a convenient version of it so many times I'd really like to stop doing that :)
In examples, perhaps. In real code, less so - often you work in F or Stream[F, ?] and the simplest way to add a debugging print will still be
Assuming we have
Maybe I'm being unreasonable a bit, but having
Have been thinking about
Console and the truth is I'd rather not have it in Cats-Effect.
The reason is that it's insufficiently well defined and we cannot do a better job in defining it without introducing complexity in Cats-Effect.
For example I was about to add a comment saying that I don't like
def error as a name, because
error is a noun and it works as a function when it's a builder / data constructor, like is the case for
But then I realized that the problem is actually larger than just naming. The problem is that users want to override the file handle they use for printing stuff.
This is why Java defines a PrintStream, and then
System.err are just print streams pointing to the standard STDOUT and STDERR, so you have the same
println function for both.
In other words, we don't actually want
def error, what we want is a
putStrLn that accepts a channel as an argument.
readLine, Java defines
System.in as an
InputStream, meaning that the same logic you define for reading from the standard input can be applied to reading from files or network sockets.
Console is convenient, but it's not convenient enough and we'd be doing a worse job than Java's standard library at composability, introducing notions that are not reusable and only useful for "Hello, World!" type programs. Say what you will of Java's impurity and its blocking I/O, but the standard library achieves the sort of decoupling that we'd do well to learn from ;-)
And maybe it would be a useful endeavor to start building pure I/O abstractions for dealing with such basic tasks, but it cannot be part of Cats-Effect's core.
Thanks for your thoughts @alexandru . I agree with you in some parts.
This could be one way to do it. For example,
def showLines[F[_]: Sync, I: Show](out: PrintStream): Sink[F, I] = _.map(_.show).to(lines(out)) def showLinesStdOut[F[_]: Sync, I: Show]: Sink[F, I] = showLines(Console.out)
A bunch of
stdinLn :: MonadIO m => Stream (Of String) m () readLn :: (MonadIO m, Read a) => Stream (Of a) m () stdoutLn :: MonadIO m => Stream (Of String) m () -> m ()
I disagree here. I think it's a nice to have "user-opt" datatype and nothing more.
I don't know whether
That's not an alternative, as what you're showing piggybacks on Java's standard library. All streaming abstractions piggyback on top of operations that are oblivious of streaming.
At the end of the day, the most fine grained operation available to us is nothing more than AsynchronousFileChannel.write, which is basically:
def write(channel: Channel, content: Array[Byte], position: Int): IO[Unit]
See also Haskell's hPutStrLn.
Nice to have doesn't cut it imo.
When it comes to products and libraries, what you leave out is just as important as what you're including.
My objection to
If we can come up with something sane, it can be an optional sub-project of cats-effect, but it's not an easy endeavor.
I was under the impression that that's what we are doing, being Cats-Effect's entire raison d'être.