Skip to content

Instantly share code, notes, and snippets.

@ismasan
Created July 22, 2022 13:00
Show Gist options
  • Save ismasan/578c7a6b3b12bcfcae2378abe775f583 to your computer and use it in GitHub Desktop.
Save ismasan/578c7a6b3b12bcfcae2378abe775f583 to your computer and use it in GitHub Desktop.
# simple railway-style pipelines for Crystal
class Success(T)
def initialize(@value : T)
end
def then(callable : T -> Success(T) | Failure(T))
callable.call(@value)
end
def then(callable : Proc(T, T))
callable.call(@value)
end
def then(&block : T -> Success(T) | Failure(T))
yield @value
end
end
class Failure(T)
def initialize(@value : T, @error : String)
end
def then(callable : T -> Success(T) | Failure(T))
self
end
def then(callable : Proc(T, T))
self
end
def then(&block : T -> Success(T) | Failure(T))
self
end
end
times_two = ->(v : Int32) { Success.new(v * 2) }
def validate(v : Int32)
Failure.new(v, "nope")
end
pp Success.new(10)
.then(->(v : Int32) { Success.new(v + 2) }) # with inline lambda
.then(times_two) # with Proc
.then(-> validate(Int32)) # with method object
.then(->(v : Int32) { Success.new(v * 3) })
.then { |v| Success.new(v * 10) } # with block
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment