4

I've been exploring the folktale library and found a wealth of useful constructs. After using Tasks via control.async and data.task, I wanted to use an IO monad, but can't seem to find it. Given how rich folktale is, I am surprised and wondering whether I just am not seeing it.

Is there an IO monad in folktale?

foxdonut
  • 7,779
  • 7
  • 34
  • 33
  • 1
    Isn't `Task Error a` equivalent to `IO a`? What exactly are you missing? – Bergi Nov 08 '15 at 21:21
  • @Bergi - please correct me if I'm wrong - isn't `Task` for async tasks? Namely, `task.fork(reject, resolve)`? I would think `IO` would be more convenient for synchronous tasks (anything that causes a side effect), being called with `io.runIO()`. – foxdonut Nov 09 '15 at 00:30
  • Uh, I thought IO is inherently async in JS, and being eager, it just runs and causes its side effects without any `runIO`. So you're just looking for a `State` monad? – Bergi Nov 09 '15 at 02:06
  • @Bergi - no. I'm looking for an `IO` monad as described in the _Old McDonald had Effects..._ section of the [Mostly Adequate Guide](https://drboolean.gitbooks.io/mostly-adequate-guide/content/ch8.html) – foxdonut Nov 09 '15 at 03:15
  • 1
    The [IO monad from monet.js](https://cwmyers.github.io/monet.js/#io) is another good example. Yes, of course I could just use that. I'm just wondering if it's already achievable with folktale. – foxdonut Nov 09 '15 at 13:01
  • 1
    @Bergi: after thinking about this for awhile, I think you are right about `Task`. Not _exactly_ what I was looking for, but serves the purpose of `IO` fairly easily. I figure they favour using the same construct for slightly different purposes instead of having too many constructs that are similar. Thanks! – foxdonut Dec 13 '15 at 23:46

1 Answers1

7

In Haskell, the IO monad is provided by (and inherently bound to), the runtime. Folktale does not provide functional equivalents for runtime functions but otherwise Task and IO serve the same purpose. An IO action in Haskell can be asynchronous, so we can say that it is even more similar to Haskell's IO than, for example, the IO monad in monet.js.

One difference is that Task provides error handling, while the IO monad doesn't.

You can program using Tasks in JS in the same manner that you program in Haskell using IO actions. You just need to define all impure runtime functions that you use using Tasks.

For example, take the function print, (print :: Show a => a -> IO ()) provided by the Haskell runtime which just prints its input and returns nothing. We can write a similar function in JS, using tasks. It will probably look something like this.

// Definition
const print = (input) => Task.task(r => {
    console.log(String(input))
    r.resolve(undefined)
})

// Usage
const main = Task.of("Hello world").chain(print)
Jencel
  • 722
  • 7
  • 17