Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Monad operators #14

Open
gilbert opened this issue Aug 29, 2014 · 0 comments
Open

Monad operators #14

gilbert opened this issue Aug 29, 2014 · 0 comments

Comments

@gilbert
Copy link
Collaborator

gilbert commented Aug 29, 2014

I'm trying to use the equivalent of >> in haskell, which discards the result of the previous call:

require 'deterministic'

class X
  extend Deterministic

  def self.util(message, ctx)
    Success(message)
  end
end

class Y
  include Deterministic

  def run(input)
    do_something(input) >> X.method(:util).to_proc.curry['it worked']
  end

  def do_something(input)
    Success(input)
  end
end

y = Y.new
puts "RESULT: #{y.run(true).inspect}"

...but using >> requires the util method to accept an additional parameter, making things less composable.


I have an idea for making Deterministic more streamline. If you're willing to make a breaking change, I think it might be better to use the three operators >=, >, and <. Although it's not nearly as cool as using >>, the advantage is they all have the same precedence.

Here is what I think each one should do:

  • >= is haskell's >>=
  • > is haskell's >>
  • < is Deterministic's pipe

Note that try is no longer an operator. I think this is ok because, thanks to functional programming, we can easily abstract it into its own method:

require 'deterministic'

class AttemptExample
  include Deterministic

  def attempt(method_name)
    lambda do |ctx|
      begin
        self.send(method_name, ctx)
      rescue Exception => e
        Failure(e)
      end
    end
  end

  def run(input)
    # Equivalent to the current do_something(input) >= method(:fail)
    do_something(input) >> attempt(:fail)
  end

  def do_something(input)
    Success(input)
  end

  def fail(input)
    raise "BOOM"
  end
end

a = AttemptExample.new
puts "RESULT: #{a.run(true).inspect}"

What do you think? I think this will make Deterministic a great joy to use! I am also open for discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant