Utilities to check whether a type M obeys the monad laws.
This module is meant to be used in test suites. It should not be imported with lazymonadlaws.
- M must have:
- A flatMap[A; B] procedure with the signature (M[A], A -> M[B]) -> M[B].
- An equality operator.
Concepts cannot currently be used to implement the monad concept in Nim. See this related issue .
- Examples:
Types
LeftIdentitySpec[A; MA; MB] = tuple[initial: A, lift: A -> MA, f: A -> MB]
- Parameters for the left identity law. Source Edit
RightIdentitySpec[T; M] = tuple[expected: T, lift: T -> M]
- Parameters for the right identity law. Source Edit
AssociativitySpec[A; B; MA; MB; MC] = tuple[initial: A, lift: A -> MA, f: A -> MB, g: B -> MC]
- Parameters for the associativity law. Source Edit
MonadLawsSpec[LA; LMA; LMB; RT; RM; AA; AB; AMA; AMB; AMC] = tuple[ leftIdentity: LeftIdentitySpec[LA, LMA, LMB], rightIdentity: RightIdentitySpec[RT, RM], associativity: AssociativitySpec[AA, AB, AMA, AMB, AMC]]
- Source Edit
Funcs
func leftIdentitySpec[A; MA; MB](initial: A; lift: A -> MA; f: A -> MB): LeftIdentitySpec[A, MA, MB]
-
- lift: A procedure to lift a value to a monad.
- f: The procedure passed to flatMap defined by the tested monad type.
- runArg: The argument passed to run as defined in LazyMonad.
func rightIdentitySpec[T; M](expected: T; lift: T -> M): RightIdentitySpec[T, M]
-
- expected: The starting value on the left side of the equation, the final value on the right side.
- lift: A procedure to lift a value to a monad.
- runArg: The argument passed to run as defined in LazyMonad.
func associativitySpec[A; B; MA; MB; MC](initial: A; lift: A -> MA; f: A -> MB; g: B -> MC): AssociativitySpec[ A, B, MA, MB, MC]
-
- lift: A procedure to lift a value to a monad.
- f: The procedure passed to the first flatMap defined by the tested monad type.
- g: The procedure passed to the second flatMap defined by the tested monad type.
- runArg: The argument passed to run as defined in LazyMonad.
func monadLawsSpec[LA; LMA; LMB; RT; RM; AA; AB; AMA; AMB; AMC]( leftIdentity: LeftIdentitySpec[LA, LMA, LMB]; rightIdentity: RightIdentitySpec[RT, RM]; associativity: AssociativitySpec[AA, AB, AMA, AMB, AMC]): MonadLawsSpec[LA, LMA, LMB, RT, RM, AA, AB, AMA, AMB, AMC]
- Source Edit
Templates
template checkLeftIdentity[A; MA; MB](spec: LeftIdentitySpec[A, MA, MB]): bool
-
Checks whether a.lift().flatMap(f) == f(a).
Lifting a value a to a monad, and binding f to it should be the same as applying f to a.
Source Edit template checkRightIdentity[T; M](spec: RightIdentitySpec[T, M]): bool
-
Checks whether a.lift().flatMap(lift) == a.lift().
Lifting a value a, and binding the same lift procedure to it should be the same as lifting a.
Source Edit template checkAssociativity[A; B; MA; MB; MC]( spec: AssociativitySpec[A, B, MA, MB, MC]): bool
-
Checks whether a.lift().flatMap(f).flatMap(g) == a.lift().flatMap(f.chain(m => m.flatMap(g))).
Lifting a value a, binding f, then g to it should be the same as lifting a and binding f.chain(m => m.flatMap(g)).
Source Edit template checkMonadLaws[LA; LMA; LMB; RT; RM; AA; AB; AMA; AMB; AMC]( spec: MonadLawsSpec[LA, LMA, LMB, RT, RM, AA, AB, AMA, AMB, AMC]): bool
- Source Edit