Skip to content

Commit

Permalink
Remove Eff.handle_relay, EffectHandler wraps it now
Browse files Browse the repository at this point in the history
  • Loading branch information
timhabermaas committed Jan 30, 2016
1 parent 8337148 commit 3458de2
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ For example: You could add logging and caching to your effect handlers at the bo
## Caveats

*No do notation*: There's no do notation in Ruby to get rid of the nested `bind` calls which remind one of callback hell. There exists [`do_notation`](https://github.com/aanand/do_notation), but it is no longer maintained. Using [`method_source`](https://github.com/banister/method_source) in combination with [`ruby_parser`](https://github.com/seattlerb/ruby_parser) might be an alternative to get the same features. I'm currently working on it at [`ruby_monad`](https://github.com/timhabermaas/ruby_monad).

*Performance*: It's pretty slow right now for a large number of chained effects.

## Contributing

Expand Down
19 changes: 0 additions & 19 deletions lib/eff.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,6 @@ def self.send(effect)
Impure.new(effect, -> (x) { Pure.new(x) })
end

def self.handle_relay(ret, impure_hash)
lambda do |eff|
self.loop(eff, ret, impure_hash)
end
end

def self.loop(eff, ret, impure_hash)
case eff
when Impure
if impure_hash.key?(eff.v.class)
self.loop(impure_hash.fetch(eff.v.class).call(eff.v, eff.k), ret, impure_hash)
else
Eff::Impure.new(eff.v, -> (x) { self.loop(eff.k.call(x), ret, impure_hash) })
end
when Pure
ret.call(eff.value)
end
end

def self.run(eff)
case eff
when Pure
Expand Down
21 changes: 20 additions & 1 deletion lib/eff/effect_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,26 @@ def on_pure(&block)
end

def run(effect)
Eff.handle_relay(@pure_handler, @impure_handlers).call(effect)
handle_relay(@pure_handler, @impure_handlers).call(effect)
end

private
def handle_relay(ret, impure_hash)
_loop = lambda do |eff, ret, impure_hash|
case eff
when Impure
if impure_hash.key?(eff.v.class)
_loop.call(impure_hash.fetch(eff.v.class).call(eff.v, eff.k), ret, impure_hash)
else
Eff::Impure.new(eff.v, -> (x) { _loop.call(eff.k.call(x), ret, impure_hash) })
end
when Pure
ret.call(eff.value)
end
end
lambda do |eff|
_loop.call(eff, ret, impure_hash)
end
end
end
end
8 changes: 5 additions & 3 deletions spec/eff/reader_effect_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ def self.ask
end

def self.run(context, effect)
Eff.handle_relay(-> (e) { Eff::Freer.return e },
{ ReaderEff::Reader => -> (r, k) {k.call(context)} }
)[effect]
Eff::EffectHandler.new
.on_impure(ReaderEff::Reader) do |r, k|
k.call(context)
end
.run(effect)
end
end

Expand Down

0 comments on commit 3458de2

Please sign in to comment.