Skip to content

Instantly share code, notes, and snippets.

@williammartin
Last active February 16, 2023 17:48
Show Gist options
  • Save williammartin/0e15f943720dadb8c6df8ca63cfbabaf to your computer and use it in GitHub Desktop.
Save williammartin/0e15f943720dadb8c6df8ca63cfbabaf to your computer and use it in GitHub Desktop.
# typed: strict
require 'sorbet-runtime'
require_relative "./result"
module Option
extend T::Sig
extend T::Helpers
extend T::Generic
interface!
sealed!
ValueType = type_member { { upper: Object } }
sig {
type_parameters(:T)
.params(value: T.all(T.type_parameter(:T), Object))
.returns(Option[T.all(T.type_parameter(:T), Object)])
}
def self.some(value)
Some.new(value)
end
sig { returns(Option[T.untyped]) }
def self.none
None.new
end
sig { abstract.returns(ValueType) }
def unwrap; end
sig {
abstract
.type_parameters(:U)
.params(block: T.proc.params(arg0: ValueType).returns(T.all(T.type_parameter(:U), Object)))
.returns(Option[T.all(T.type_parameter(:U), Object)])
}
def map(&block); end
sig {
abstract
.type_parameters(:U)
.params(block: T.proc.params(arg0: ValueType).returns(Option[T.all(T.type_parameter(:U), Object)]))
.returns(Option[T.all(T.type_parameter(:U), Object)])
}
def flat_map(&block); end
sig {
abstract
.type_parameters(:E)
.params(err: T.all(T.type_parameter(:E), Object))
.returns(Result[
ValueType,
T.all(T.type_parameter(:E), Object)
])
}
def ok_or(err); end
class Some
extend T::Sig
extend T::Generic
include Option
ValueType = type_member { { upper: Object } }
sig { params(value: ValueType).void }
def initialize(value)
@value = value
end
sig { override.returns(ValueType) }
def unwrap
@value
end
sig {
override
.type_parameters(:U)
.params(block: T.proc.params(arg0: ValueType).returns(T.all(T.type_parameter(:U), Object)))
.returns(Option[T.all(T.type_parameter(:U), Object)])
}
def map(&block)
Some.new(block.call(@value))
end
sig {
override
.type_parameters(:U)
.params(block: T.proc.params(arg0: ValueType).returns(Option[T.all(T.type_parameter(:U), Object)]))
.returns(Option[T.all(T.type_parameter(:U), Object)])
}
def flat_map(&block)
block.call(@value)
end
sig {
override
.type_parameters(:E)
.params(err: T.all(T.type_parameter(:E), Object))
.returns(Result[
ValueType,
T.all(T.type_parameter(:E), Object)
])
}
def ok_or(err)
Result.ok(@value)
end
end
class None
extend T::Sig
extend T::Generic
include Option
ValueType = type_member { { upper: Object } }
sig { override.returns(T.noreturn) }
def unwrap
raise UnwrapError.new
end
sig {
override
.type_parameters(:U)
.params(block: T.proc.params(arg0: ValueType).returns(T.all(T.type_parameter(:U), Object)))
.returns(Option[T.all(T.type_parameter(:U), Object)])
}
def map(&block)
None.new
end
sig {
override
.type_parameters(:U)
.params(block: T.proc.params(arg0: ValueType).returns(Option[T.all(T.type_parameter(:U), Object)]))
.returns(Option[T.all(T.type_parameter(:U), Object)])
}
def flat_map(&block)
None.new
end
sig {
override
.type_parameters(:E)
.params(err: T.all(T.type_parameter(:E), Object))
.returns(Result[
ValueType,
T.all(T.type_parameter(:E), Object)
])
}
def ok_or(err)
Result.err(err)
end
end
class UnwrapError < StandardError
extend T::Sig
sig { returns(String) }
def message
"called `Option::unwrap` on a None"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment