MonadError in cats has the following laws:
- L1:
handle(raise(e))(f) == f(e) - L2:
pure(a) >>= (_ => raise(e)) == raise(e) - L3:
raise(e) >>= (_ => point(a)) == raise(e)
And it is defined roughly like this:
trait MonadError[F[_], E] {| from collections import namedtuple | |
| PutStrLn = namedtuple('PutStrLn', 'value') | |
| Read = namedtuple('Read', []) | |
| def hello(): | |
| _ = yield PutStrLn('Hello.') | |
| return True | |
| def f(myname): |
| #!/usr/bin/env python | |
| from struct import pack, unpack | |
| import re | |
| import os, errno | |
| import os.path | |
| def mkdir_p(path): | |
| try: | |
| os.makedirs(path) |
| import cats.{MonadError, Monad} | |
| import cats.data.Xor | |
| import scala.annotation.tailrec | |
| object io { | |
| object unsafe { | |
| type Val = Any with ({ type Tag = Any }) | |
| object Val { |
| def train_adadelta(func, fprime, x0, x_min, x_max, | |
| step_rate=1, decay=0.9, momentum=0, offset=1e-4, | |
| iterations=1000, tolerance=1e-1): | |
| x_min = x_min if x_min is not None else (np.ones_like(x0) * (-np.inf)) | |
| x_max = x_max if x_max is not None else (np.ones_like(x0) * np.inf) | |
| clamp = lambda x: np.where(x < x_min, x_min, | |
| np.where(x > x_max, x_max, x)) | |
| bounce = lambda x, dx: np.where(x + dx < x_min, x_min - x, | |
| np.where(x + dx > x_max, x_max - x, dx)) |
| import cats.Applicative | |
| import cats.instances.list._ | |
| import cats.instances.option._ | |
| import cats.syntax.functor._ | |
| import cats.Id | |
| trait Instance[TC[_]] { | |
| type Type | |
| def value: Type | |
| def typeclass: TC[Type] |
| import cats.kernel.Group | |
| /** | |
| * http://math.ucr.edu/home/baez/torsors.html | |
| * https://en.wikipedia.org/wiki/Heap_(mathematics) | |
| * https://en.wikipedia.org/wiki/Affine_space | |
| */ | |
| trait Torsor[P] extends Any { | |
| type V | |
| def group: Group[V] |
| sealed trait Decidable[+Proof] | |
| final case class Yes[Proof](proof: Proof) extends Decidable[Proof] | |
| final case object No extends Decidable[Nothing] | |
| sealed trait List[+A] { | |
| def nonEmpty: Decidable[this.type <:< ::[A]] | |
| def ::[AA >: A](value: AA): ::[AA] = new ::[AA](value, this) | |
| } | |
| final case object Nil extends List[Nothing] { | |
| def nonEmpty: Decidable[this.type <:< ::[Nothing]] = No |
| trait Foo { | |
| // Represents natural numbers or expressions resulting in natural numbers. | |
| trait Nat { | |
| // The actual value (e.g. for 1 + 3 * 2, this would be 7). | |
| type Result <: Nat1 | |
| // Fold. | |
| type Fold[K, z <: K, s[_ <: Nat] <: K] <: K | |
| // Catamorphism. | |
| type Cata[K, z <: K, s[_ <: K] <: K] <: K | |
| } |
| trait Eq[A] { | |
| def eqv(a: A, b: A): Boolean | |
| } | |
| trait Law | |
| // For all types A with constraint G[A] ... | |
| trait Λ[G[_], L[_] <: Law] extends Law { | |
| def apply[A](implicit A: G[A]): L[A] | |
| } | |
| // and for all values of type A ... |