Hello everyone, I got a simple console program, t...
# arrow
b
Hello everyone, I got a simple console program, that reads to numbers from console and prints the sum. I have learned that the FP way of effects is not to use IO<Unit> for everything, because that does not give us control of which types of effects we want to allow for certain parts of our code. Thus I want to allow only console reading and printing or console IO for this program, how would I do that with arrow-fx?
Copy code
fun add(a: Int, b: Int): Int = a + b

suspend fun main1(args: Array<String>) =
    IO.fx {

        val sc = Scanner(System.`in`)

        val nextInt = effect { sc.nextInt() }

        val added = IO.applicative()
            .map(nextInt, nextInt) { (a, b) -> add(a, b) }.bind()

        effect { println(added) }.bind()

    }.run { suspended() }
p
For that you'll need to use an interpreter pattern. Sometimes we call it an algebra and interpreter. You define a sealed class with the operations you'd like to allow, and a function that knows how to translate those to
IO
operations to run them. The examples we have that look like this are mostly the Free Monad ones, which is just an implementation detail.
b
Ok, I see. Something like:
Copy code
sealed class IoOperations {
    object ReadConsole : IoOperations()
    object PrintConsole : IoOperations()
}
p
yes, and you put the function parameters as fields of the class
another common pattern is also making the output of the function a generic
in your case it’s a side-effect, still
Copy code
sealed class IoOperations<T> {
    object ReadConsole : IoOperations<Unit>()
    object PrintConsole : IoOperations<Unit>()
}
p
🔝 1
❤️ 1