The Either Monad¶
-
class
hymn.types.either.
Either
(value)¶ Bases:
hymn.types.monadplus.MonadPlus
,hymn.mixins.Ord
the either monad
computation with two possibilities
-
class
hymn.types.either.
Left
(value)¶ Bases:
hymn.types.either.Either
left of
Either
-
class
hymn.types.either.
Right
(value)¶ Bases:
hymn.types.either.Either
right of
Either
-
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
Reader Macro¶
-
| [f]
turn
f
into monadic function withfailsafe()
Functions¶
-
->either
-
to-either
alias of
Either.from_value()
-
left?
alias of
is_left()
-
right?
alias of
is_right()
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]])
=> (do-monad [a (Right 1) b (Right 2)] (+ a b))
Right(3)
=> (do-monad [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 (zero? 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 inc (Left 1))
1
=> (either print inc (Right 1))
2
failsafe()
turns function into monadic one
=> (import [hymn.types.either [failsafe]])
=> (with-decorator failsafe (defn add1 [n] (inc (int n))))
=> (add1 "41")
Right(42)
=> (add1 "nan")
Left(ValueError("invalid literal for int() with base 10: 'nan'",))
=> (def 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 [|]])
=> (#|int "42")
Right(42)
=> (#|int "nan")
Left(ValueError("invalid literal for int() with base 10: 'nan'",))
=> (def safe-div #|/)
=> (safe-div 1 2)
Right(0.5)
=> (safe-div 1 0)
Left(ZeroDivisionError('division by zero',))