Type Attributes
Types themselves have optional attributes you can apply to get further functionality.
Append .optional
to a Type to allow nil
By default, nil values raise an error:
Types::Strict::String[nil]
# => raises Dry::Types::ConstraintError
Add .optional
and nil
values become valid:
optional_string = Types::Strict::String.optional
optional_string[nil]
# => nil
optional_string['something']
# => "something"
optional_string[123]
# raises Dry::Types::ConstraintError
Types::String.optional
is just syntactic sugar for Types::Strict::Nil | Types::Strict::String
.
Handle optional values using Monads
The dry-monads gem provides another approach to handling optional values by returning a Monad object. This allows you to pass your type to a Maybe(x)
block that only executes if x
returns Some
or None
.
NOTE: Requires the dry-monads gem to be loaded.
Load the
:maybe
extension in your application.require 'dry-types' Dry::Types.load_extensions(:maybe) module Types include Dry.Types() end
Append
.maybe
to a Type to return a Monad object
x = Types::Maybe::Strict::Integer[nil]
Maybe(x) { puts(x) }
x = Types::Maybe::Coercible::String[nil]
Maybe(x) { puts(x) }
x = Types::Maybe::Strict::Integer[123]
Maybe(x) { puts(x) }
x = Types::Maybe::Strict::String[123]
Maybe(x) { puts(x) }
Types::Maybe::Strict::Integer[nil] # None
Types::Maybe::Strict::Integer[123] # Some(123)
Types::Maybe::Coercible::Float[nil] # None
Types::Maybe::Coercible::Float['12.3'] # Some(12.3)
# 'Maybe' types can also accessed by calling '.maybe' on a regular type:
Types::Strict::Integer.maybe # equivalent to Types::Maybe::Strict::Integer
You can define your own optional types:
maybe_string = Types::Strict::String.maybe
maybe_string[nil]
# => None
maybe_string[nil].fmap(&:upcase)
# => None
maybe_string['something']
# => Some('something')
maybe_string['something'].fmap(&:upcase)
# => Some('SOMETHING')
maybe_string['something'].fmap(&:upcase).value_or('NOTHING')
# => "SOMETHING"