The Either Monad¶
- class hymn.types.either.Either¶
the either monad
computation with two possibilities
- bind(self, f)¶
the bind operation of
Either
apply function to the value if and only if this is a
Right
.
- plus(self, other)¶
- hymn.types.either.either(handle_left, handle_right m)¶
case analysis for
Either
apply either
handle-left
orhandle-right
tom
depending on the type of it, raiseTypeError
ifm
is not anEither
- hymn.types.either.to_either()¶
alias of
from_value()
Hy Specific API¶
- either-m
alias of
Either
- ->either
alias of
from_value()
- left?
alias of
is_left()
- right?
alias of
is_right()
Reader Macro¶
- | [f]
turn
f
into monadic function withfailsafe()
Examples¶
Comparison¶
Either are comparable if the wrapped values are comparable. Right
is
greater than Left
in any case.
=> (import hymn.types.either [Left Right])
=> (> (Right 2) (Right 1))
True
=> (< (Left 2) (Left 1))
False
=> (> (Left 2) (Right 1))
False
Do Notation¶
=> (import hymn.types.either [Left Right])
=> (require hymn.macros [do-monad-return])
=> (do-monad-return [a (Right 1) b (Right 2)] (+ a b))
Right(3)
=> (do-monad-return [a (Left 1) b (Right 2)] (+ a b))
Left(1)
Do Notation with :when¶
=> (import hymn.types.either [either-m])
=> (require hymn.macros [do-monad-with])
=> (defn safe-div [a b]
... (do-monad-with either-m [:when (not (= 0 b))] (/ a b)))
=> (safe-div 1 2)
Right(0.5)
=> (safe-div 1 0)
Left('unknown error')
Operations¶
Use ->either
to create an Either
from a value
=> (import hymn.types.either [->either])
=> (->either 42)
Right(42)
=> (->either None)
Left(None)
Use left?()
and right?()
to test the type
=> (import hymn.types.either [Left Right left? right?])
=> (right? (Right 42))
True
=> (left? (Left None))
True
either()
applies function to value in the monad depending on the type
=> (import hymn.types.either [Left Right either])
=> (either print (fn [x] (+ x 1)) (Left 1))
1
=> (either print (fn [x] (+ x 1)) (Right 1))
2
failsafe()
turns function into monadic one
=> (import hymn.types.either [failsafe])
=> (defn [failsafe] add1 [n] (+ 1 (int n)))
=> (add1 "41")
Right(42)
=> (add1 "nan")
Left(ValueError("invalid literal for int() with base 10: 'nan'"))
=> (import hy.pyops [/])
=> (setv safe-div (failsafe /))
=> (safe-div 1 2)
Right(0.5)
=> (safe-div 1 0)
Left(ZeroDivisionError('division by zero'))
Reader Macro¶
=> (require hymn.types.either :readers [|])
=> (#| int "42")
Right(42)
=> (#| int "nan")
Left(ValueError("invalid literal for int() with base 10: 'nan'"))
=> (import hy.pyops [/])
=> (setv safe-div #| /)
=> (safe-div 1 2)
Right(0.5)
=> (safe-div 1 0)
Left(ZeroDivisionError('division by zero'))