Dear Russian friends, please watch President Zelenskyy's speech addressed to you. πŸ‡ΊπŸ‡¦Help our brave mates in Ukraine with a donation.


The monads extension makes Dry::Schema::Result objects compatible with dry-monads.

To enable the extension:

require 'dry/schema'


After loading the extension, you can leverage monad API:

schema = Dry::Schema.Params { required(:name).filled(:string, size?: 2..4) } 'Jane').to_monad # => Dry::Monads::Success(#<Dry::Schema::Result{:name=>"Jane"} errors={}>) '').to_monad     # => Dry::Monads::Failure(#<Dry::Schema::Result{:name=>""} errors={:name=>["must be filled"]}>)

schema.(name: "")
  .fmap { |r| puts "passed: #{r.to_h.inspect}" }
  .or   { |r| puts "failed: #{r.errors.to_h.inspect}" }

This can be useful when used with dry-monads and do notation.

Using with pattern matching

Ruby 2.7 adds experimental support for pattern matching. Both dry-schema and dry-monads work with it nicely:

require 'dry/schema'
require 'dry/monads'


class Example
  include Dry::Monads[:result]

  Schema = Dry::Schema.Params { required(:name).filled(:string, size?: 2..4) }

  def call(input)
    case schema.(input).to_monad
    in Success(name:)
      "Hello #{name}" # name is captured from result
    in Failure(name:)
      "#{name} is not a valid name"

run =

run.('name' => 'Jane')   # => "Hello Jane"
run.('name' => 'Albert') # => "Albert is not a valid name"

octocatEdit on GitHub