redux-saga is a lot like an IO monad
See original GitHub issueHello @yelouafi.
I’ve been thinking about how redux-saga has a lot in common with the IO monad from purely functional languages. But you’ve likely realized that as well. I’ve been using redux-saga for a project at work and I’m thoroughly enjoying it. But even though I can understand that it was inspired by the saga pattern I always think of it as an IO monad 😄
It occurred to me that the use of generators is reminiscent of Haskell’s do-notation. In fact Fantasy Do uses generator functions to implement do-notation for fantasy land monads.
I’ve played a little with the idea of implementing an IO-monad in JavaScript and using it with Fantasy Do like do-notation. Do you think such a thing is viable? One restriction would be that the do-notation would only allow one to yield
IO-monad’s whereas redux-saga gives the user a lot of flexibility about what to yield
.
I can see that there has previously (#16) been talk about decoupling redux-saga from redux. What is your thoughts about that now? I think a general purpose declarative effects library for JS could be interesting albeit probably not to an audience as wide as the Redux userbase.
Issue Analytics
- State:
- Created 7 years ago
- Reactions:4
- Comments:6 (4 by maintainers)
Top GitHub Comments
You could go with a monorepo with the two packages in the same repo! That’d solve the issue problem
Thanks for the great replies 😄
@slorber
I have seen that you’ve mentioned the Free monad in other threads. It’s very interesting. I have been reading a bit about the Free monad. I don’t really understand it yet but I partly understand the similarity with redux-saga. In Haskell a function with the type
Integer -> IO (String)
conceptually returns a description of an action that produces aString
when executed. In this sense it is very similar to redux-saga. But as you mention, the difference is thatIO
is completely opaque unlike saga actions that can be inspected and tested. If I understand correctly thenFree
accounts for this since it can be used to build up transparent AST structures that can be interpreted in several ways. But in the special case where the AST is simply executed it is similar to the IO monad. That is my current understanding. Please correct me if I’m wrong.@yelouafi
You are indeed right that
IO
is opaque, but conceptually it’s just data. I guess the reason for the opaqueness is so that it allows forIO
-code to be compiled into efficient machine code where theIO
construct doesn’t exist at run-time.Testing
IO
code in Haskell is much like testing imperative JavaScript code: hard and messy 😭 It certainly doesn’t have the advantages that redux-saga has.Monads are indeed sequential. But each line in a saga is also executed sequentially isn’t it? Line number 2 in a saga is never run before line number 1? It seems to me like it matches monads. I actually think the asynchronous features in redux-saga are covered by concurrency in the
IO
monad.fork
in saga is likeforkIO
,call
in saga is like a blockingIO
action,cancel
in saga is likekillThread
.Yes. That is a quite sad restriction. Especially because it breaks the abstraction in Fantasy Do. You can’t use the same do-notation with all monads. To solve this and other issues I’m working on a fantasy land replacement, jabz. I’m planning to specify it so that each monad must declare if it is multi or not. Then do-notation can be implemented so that it works for all monads and without the awkwardness in Fantasy Do.