Skip to main content

Posts

Showing posts with the label cats-effects

Process text file concurrently

 Process the same input file concurrently Let's say we have a text file that contains 2 different types of lines.  For the sake of example, one group starts with "i:" (for Integer) and the other group starts with "s:" (for String), something like the following file: s:New york s:Apple i:387548 s:Amsterdam i:4556 i:39874 s:Orange i:56787 s:Banana i:4657567 s:Turkey i:45679456 s:Iran i:4356456 i:23423 i:456 s:Ukraine i:453645 i:5456 We want to process these input lines separately but concurrently. And the process can be anything, for this example, we just print them to the console. But what matters is that we open the file only for READ so 2 different processes (or routines) can read the file at the same time. The Cats Effect answer to open files (or in general any resources) in a safe and efficient way, is  Resource class. So we need a function to take the path to the file and give us a Resource of some type that allows us to read the file line by line. One o...

Process text file concurrently

 Process the same input file concurrently Let's say we have a text file that contains 2 different types of lines.  For the sake of example, one group starts with "i:" (for Integer) and the other group starts with "s:" (for String), something like the following file: s:New york s:Apple i:387548 s:Amsterdam i:4556 i:39874 s:Orange i:56787 s:Banana i:4657567 s:Turkey i:45679456 s:Iran i:4356456 i:23423 i:456 s:Ukraine i:453645 i:5456 We want to process these input lines separately but concurrently. And the process can be anything, for this example, we just print them to the console. But what matters is that we open the file only for READ so 2 different processes (or routines) can read the file at the same time. The Cats Effect answer to open files (or in general any resources) in a safe and efficient way, is  Resource class. So we need a function to take the path to the file and give us a Resource of some type that allows us to read the file line by line. One o...

HTTP Client function as IO of String

In this super short post, I am showing you how to write a very naive HTTP client ( GET ) to return the content of the response as a plain String . The whole point here is not to use a proper Scala library and wrap the side effect (an HTTP request is a side effect) in an IO object. object HttpService { def getRequest(uri: String): IO[String] = { try { IO { val url = new URL(uri) val con = url.openConnection.asInstanceOf[HttpURLConnection] con.setRequestMethod("GET") val streamReader = getTheStreamReader(con) val bufferedReader = new BufferedReader(streamReader) def loop(reader: BufferedReader, stringBuilder: StringBuilder): StringBuilder = { val line = reader.readLine() line match case null => stringBuilder case line => loop(reader, stringBuilder.append(line)) } loop(bufferedReader, new StringBuilder()).toString() } } catch { case t:...

IO class exercises (part 2)

In this post, I try to show you some more examples of fundamental tasks on an IO object. We have seen 3 of these examples in the part one of IO class exercises . Exercise 4:  Writing a function that takes an IO object and converts it to another data type: def convert[A, B](ioa: IO[A], value: B): IO[B] = ??? Of course, we want to wrap the value in an IO but also we want to make sure the receiving IO of A has been completed. We can use the famous map method that a monad has. def convert[A, B](ioa: IO[A], value: B): IO[B] = ioa.map(_ => value) This map operation on IO is so popular that there is method for that on IO class, so we can write the second version of this function like: def convert[A, B](ioa: IO[A], value: B): IO[B] = ioa.as(value)

IO class excercises

 In the last post, we used the IO class (of cats-effects library ) to do side effects or simply effects in a pure function .  In this post, we will practice IO class a bit more. We write some functions that do some very useful and popular stuff on one or more IO objects. Exercise 1: Sequencing two IO objects and returning the second one. Meaning that we want to write a function that takes two IO objects of type A and B and returns an IO of type B, but only after making sure the IO of A is completed. The method signature should look like this: def sequenceTakeLast[A, B](ioa: IO[A], iob: IO[B]): IO[B] = ??? For writing this function we should remember that the IO class is a monad and it has all the methods that a monad has. Including the flatMap method. There are 2 sub-tasks: We want to return the IO of B We want to make sure the IO of A is completed first def sequenceTakeLast[A, B](ioa: IO[A], iob: IO[B]): IO[B] = { ioa.flatMap(_ => iob.map(b => b)) } As you mig...

Using IO class to perform side-effects in a pure functional way

  Cats-effects ' IO class is the answer of the library to performing side effects (or simply effects) in a functional way. Functional programming is focused on pure functions and a pure function is a function that does not perform any side effects but only produces an output based on the receiving inputs. Real-world programs are far from this mathematical abstract definition. A program with no side effects is doing nothing as most of the useful things are side effects, such as writing to a database, writing to a file, reading from a file, printing on the screen, and ... An IO class is actually a description of a computation, rather than the execution of that computation. That's why it will not make a function an impure function. Example: Printing on the screen (which is a side effect), as some sort of logging. If we want to print on the screen using inside the body of a function the side effect happens but if we return the effect as an IO object wrapping the calculation result...