Skip to content

Instantly share code, notes, and snippets.

@dodecaphonic
Last active January 30, 2022 22:33
Show Gist options
  • Save dodecaphonic/7d9afb7814df7bad99aebb43374a0a74 to your computer and use it in GitHub Desktop.
Save dodecaphonic/7d9afb7814df7bad99aebb43374a0a74 to your computer and use it in GitHub Desktop.
Trying to encode a RIO-like thing in Ruby's RBS
class RIO
def self.succeed_now(value)
Succeed.new(value)
end
def self.fail_now(error)
Fail.new(error)
end
def flat_map(&blk)
FlatMap.new(self, &blk)
end
def map(&blk)
FlatMap.new(self) { |a| Succeed.new(blk.call(a)) }
end
def flumb(a, b)
RIO.succeed_now([a, b])
end
def zip(other)
flat_map { |a| other.map { |b| [a, b] } }
end
end
class Fail < RIO
def initialize(error)
@error = error
end
def run
self
end
end
class Succeed < RIO
def initialize(value)
@value = value
end
def run
yield @value
end
end
class FlatMap < RIO
def initialize(rio, &fn)
@rio = rio
@fn = fn
end
def run
@rio.run(&@fn)
end
end
class RIO[R, E, A]
def self.succeed_now: [R, E, A] (A) -> RIO[R, E, A]
def self.fail_now: [R, E, A] (E) -> RIO[R, E, A]
def map: [B] { (A) -> B } -> RIO[R, E, B]
def flat_map: [B] { (A) -> RIO[R, E, B] } -> RIO[R, E, B]
def run: { (A) -> void } -> void
def zip: [B] (RIO[R, E, B]) -> RIO[R, E, [A, B]]
def flumb: [Q, Y] (Q, Y) -> RIO[R, E, [Q, Y]]
end
class Fail[R, E, A] < RIO[R, E, A]
@error: E
def initialize: (E) -> void
end
class Succeed[R, E, A] < RIO[R, E, A]
@value: A
def initialize: (A) -> void
end
class FlatMap[R, E, A, B] < RIO[R, E, B]
@rio: RIO[R, E, A]
@fn: ^(A) -> RIO[R, E, B]
def initialize: (RIO[R, E, A]) { (A) -> RIO[R, E, B] } -> void
end
@dodecaphonic
Copy link
Author

$ be steep watch ./lib ./sig
πŸ‘€ Watching directories, Ctrl-C to stop.
lib/rio.rb:18:6: [error] Cannot allow method body have type `::RIO[untyped, untyped, ::Array[(Q | Y)]]` because declared as type `::RIO[R, E, [Q, Y]]`
β”‚   ::RIO[untyped, untyped, ::Array[(Q | Y)]] <: ::RIO[R, E, [Q, Y]]
β”‚     ::Array[(Q | Y)] <: [Q, Y]
β”‚
β”‚ Diagnostic ID: Ruby::MethodBodyTypeMismatch
β”‚
β””   def flumb(a, b)
        ~~~~~
lib/rio.rb:22:6: [error] Cannot allow method body have type `::RIO[R, E, ::Array[(A | B)]]` because declared as type `::RIO[R, E, [A, B]]`
β”‚   ::RIO[R, E, ::Array[(A | B)]] <: ::RIO[R, E, [A, B]]
β”‚     ::Array[(A | B)] <: [A, B]
β”‚
β”‚ Diagnostic ID: Ruby::MethodBodyTypeMismatch
β”‚
β””   def zip(other)
        ~~~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment