Skip to content

Instantly share code, notes, and snippets.

@williammartin
Last active February 15, 2023 14:13
Show Gist options
  • Save williammartin/493d4c1b6f9d1547e6a1bc40408e39c9 to your computer and use it in GitHub Desktop.
Save williammartin/493d4c1b6f9d1547e6a1bc40408e39c9 to your computer and use it in GitHub Desktop.
# typed: strict
require 'sorbet-runtime'
module Result
extend T::Sig
extend T::Helpers
extend T::Generic
interface!
sealed!
OkType = type_member { { upper: Object } }
ErrorType = type_member { { upper: Object } }
sig {
type_parameters(:V)
.params(value: T.all(T.type_parameter(:V), Object))
.returns(Result[
T.all(T.type_parameter(:V), Object),
T.untyped,
])
}
def self.ok(value)
Success.new(value)
end
sig {
type_parameters(:E)
.params(value: T.all(T.type_parameter(:E), Object))
.returns(Result[
T.untyped,
T.all(T.type_parameter(:E), Object)
])
}
def self.err(value)
Failure.new(value)
end
sig { abstract.returns(OkType) }
def unwrap; end
sig {
abstract
.type_parameters(:U)
.params(block: T.proc.params(arg0: OkType).returns(T.all(T.type_parameter(:U), Object)))
.returns(Result[
T.all(T.type_parameter(:U), Object),
ErrorType,
])
}
def map(&block); end
sig {
abstract
.type_parameters(:U)
.params(block:
T.proc.params(arg0: OkType)
.returns(
Result[
T.all(T.type_parameter(:U), Object),
ErrorType
]
)
)
.returns(Result[
T.all(T.type_parameter(:U), Object),
ErrorType,
])
}
def and_then(&block); end
sig {
abstract
.type_parameters(:E)
.params(block: T.proc.params(arg0: ErrorType).returns(T.all(T.type_parameter(:E), Object)))
.returns(Result[
OkType,
T.all(T.type_parameter(:E), Object),
])
}
def map_err(&block); end
class Success
extend T::Sig
extend T::Generic
include Result
OkType = type_member { { upper: Object } }
ErrorType = type_member { { upper: Object } }
sig { params(value: OkType).void }
def initialize(value)
@value = value
end
sig { override.returns(OkType) }
def unwrap
@value
end
sig {
override
.type_parameters(:U)
.params(block: T.proc.params(arg0: OkType).returns(T.all(T.type_parameter(:U), Object)))
.returns(Result[
T.all(T.type_parameter(:U), Object),
ErrorType,
])
}
def map(&block)
Result.ok(block.call(@value))
end
sig {
override
.type_parameters(:U)
.params(block:
T.proc.params(arg0: OkType)
.returns(
Result[
T.all(T.type_parameter(:U), Object),
ErrorType
]
)
)
.returns(Result[
T.all(T.type_parameter(:U), Object),
ErrorType,
])
}
def and_then(&block)
block.call(@value)
end
sig {
override
.type_parameters(:E)
.params(block: T.proc.params(arg0: ErrorType).returns(T.all(T.type_parameter(:E), Object)))
.returns(Result[
OkType,
T.all(T.type_parameter(:E), Object),
])
}
def map_err(&block)
Result.ok(@value)
end
end
class Failure
extend T::Sig
extend T::Generic
include Result
OkType = type_member { { upper: Object } }
ErrorType = type_member { { upper: Object } }
sig { params(value: ErrorType).void }
def initialize(value)
@value = value
end
sig { override.returns(T.noreturn) }
def unwrap
raise UnwrapError.new(@value)
end
sig {
override
.type_parameters(:U)
.params(block: T.proc.params(arg0: OkType).returns(T.all(T.type_parameter(:U), Object)))
.returns(Result[
T.all(T.type_parameter(:U), Object),
ErrorType,
])
}
def map(&block)
Result.err(@value)
end
sig {
override
.type_parameters(:U)
.params(block:
T.proc.params(arg0: OkType)
.returns(
Result[
T.all(T.type_parameter(:U), Object),
ErrorType
]
)
)
.returns(Result[
T.all(T.type_parameter(:U), Object),
ErrorType,
])
}
def and_then(&block)
Result.err(@value)
end
sig {
override
.type_parameters(:E)
.params(block: T.proc.params(arg0: ErrorType).returns(T.all(T.type_parameter(:E), Object)))
.returns(Result[
OkType,
T.all(T.type_parameter(:E), Object),
])
}
def map_err(&block)
Result.err(block.call(@value))
end
end
class UnwrapError < StandardError
extend T::Sig
sig { params(value: T.untyped).void }
def initialize(value)
@value = value
end
sig { returns(String) }
def message
"called `Result::unwrap` on a Failure containing: '#{@value}'"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment