Class: Ruff::Handler

Inherits:
Object
  • Object
show all
Defined in:
lib/ruff/handler.rb

Overview

In algebraic effects, handler is an first-class object.

Instance Method Summary collapse

Constructor Details

#initializeHandler

Returns a new instance of Handler.

Examples:

handler = Handler.new


38
39
40
41
# File 'lib/ruff/handler.rb', line 38

def initialize
  @handlers = Store.new
  @valh = ->(x) { x }
end

Instance Method Details

#on(eff, &fun) ⇒ Handler<A!{Effect<Arg, Ret>, e}, B!{e}>

sets or updates effec handler &fun for eff

Note that eff can be a supertype of an effect to be caught.

Examples:

handler.on(Log) {|k, msg|
  puts "Logger: #{msg}"
  k[]
}

Parameters:

  • eff (Effect<Arg, Ret>)

    the effect instance to be handled

  • fun (Proc<Arg, Ret => A>)

    a handler to handle eff; First argument of &fun is continuation, proc object to go back to the handled computation.

Returns:

  • (Handler<A!{Effect<Arg, Ret>, e}, B!{e}>)

    itself updated with handling Effect<Arg, Ret>

See Also:



102
103
104
105
106
# File 'lib/ruff/handler.rb', line 102

def on(eff, &fun)
  @handlers[eff] = fun

  self
end

#run(&prc) ⇒ B

handles the computation.

Examples:

handler.run {
  Log.perform "hello"
}

handler can be layered.

handler.run {
  Handler.new
    .on(Double){|k, v|
      k[v * v]
    }.run {
      v = Double.perform 3
      Log.perform 3
  }
}

Parameters:

  • prc (Proc<(), A>)

    a thunk to be handled and returns A

Returns:

  • (B)

    a value modified by value handler Proc<A, B> , or returned from the effect handler throwing continuation away



131
132
133
134
135
# File 'lib/ruff/handler.rb', line 131

def run(&prc)
  co = Fiber.new(&prc)

  continue(co).call(nil)
end

#to(&fun) ⇒ Handler<A!{e}, B!{e'}>

sets value handler &fun.

Value handler is the handler for the result value of the computation. For example, Handler.new.to{|_x| 0}.run { value } results in 0 .

The value handler modifies the result of the call of continuation in effect handlers of the handler.

Examples:

logs = []
handler.on(Log) {|k, msg|
  logs << msg
  k[]
}.to {|x|
 logs.each {|log|
   puts "Logger: #{log}"
 }

  puts "returns #{x}"
}
.run {
  Log.perform "hello"
  Log.perform "world"
  "!"
}

## ==>
# msg>> hello
# msg>> world
# returns !

Parameters:

  • fun (Proc<A, B>)

    value handler

Returns:



77
78
79
80
81
# File 'lib/ruff/handler.rb', line 77

def to(&fun)
  @valh = fun

  self
end