split monad law tests, add setoid to Option and Result
This commit is contained in:
parent
48a3670172
commit
38343d7ec0
3 changed files with 54 additions and 16 deletions
|
@ -1,9 +1,9 @@
|
|||
import { Algebra, Foldable, Monad, Monoid } from './interfaces.js'
|
||||
import { Algebra, Foldable, Monad, Monoid, Setoid } from './interfaces.js'
|
||||
|
||||
/** @import { Morphism } from './types.js' */
|
||||
|
||||
/** @template T */
|
||||
export class Some extends Algebra(Monoid, Monad, Foldable) {
|
||||
export class Some extends Algebra(Setoid, Monoid, Monad, Foldable) {
|
||||
/** @type {T} */
|
||||
#value
|
||||
|
||||
|
@ -71,7 +71,7 @@ export class Some extends Algebra(Monoid, Monad, Foldable) {
|
|||
}
|
||||
|
||||
/** @template T */
|
||||
export class None extends Algebra(Monoid, Monad, Foldable) {
|
||||
export class None extends Algebra(Setoid, Monoid, Monad, Foldable) {
|
||||
equals(other) {
|
||||
return other === none
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { Algebra, Foldable, Functor, Monad } from './interfaces.js'
|
||||
import { Algebra, Foldable, Functor, Monad, Setoid } from './interfaces.js'
|
||||
|
||||
/** @import { Morphism } from './types.js' */
|
||||
|
||||
/**
|
||||
* @template T, E
|
||||
*/
|
||||
export class Ok extends Algebra(Monad, Foldable) {
|
||||
export class Ok extends Algebra(Setoid, Monad, Foldable) {
|
||||
/** @type {T} */
|
||||
#value
|
||||
|
||||
|
@ -83,7 +83,7 @@ export class Ok extends Algebra(Monad, Foldable) {
|
|||
/**
|
||||
* @template T, E
|
||||
*/
|
||||
export class Err extends Algebra(Functor, Monad) {
|
||||
export class Err extends Algebra(Setoid, Functor, Monad) {
|
||||
/** @type {E} */
|
||||
#value
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { it, assert } from 'folktest'
|
||||
import { Option, Result } from '../../src/index.js'
|
||||
|
||||
const Monads = [Option, Result]
|
||||
|
||||
const leftIdentity = (M, a, f) => {
|
||||
assert(M(a).chain(f).equals(f(a)))
|
||||
}
|
||||
|
@ -19,17 +21,53 @@ export const prove = (M, m, a, f, g) => {
|
|||
associativity(m, f, g)
|
||||
}
|
||||
|
||||
export const Tests = [
|
||||
it('should adhere to monadic laws', () => {
|
||||
[Option, Result].forEach(F => {
|
||||
const Ctr = F.of
|
||||
const inc = F => x => F.of(x + 1)
|
||||
const dbl = F => x => F.of(x * 2)
|
||||
|
||||
prove(
|
||||
Ctr,
|
||||
Ctr(1),
|
||||
1,
|
||||
x => Ctr(x + 1),
|
||||
x => Ctr(x * 2)
|
||||
export const Tests = [
|
||||
it('unit is a left identity', () => {
|
||||
Monads.forEach(monad => {
|
||||
const f = inc(monad)
|
||||
// NOTE: okay but like, shut up
|
||||
// @ts-ignore
|
||||
assert(monad.of(1).chain(f).equals(f(1)))
|
||||
})
|
||||
//prove(
|
||||
// Ctr, M
|
||||
// Ctr(1), m
|
||||
// 1, a
|
||||
// x => Ctr(x + 1), f
|
||||
// x => Ctr(x * 2) g
|
||||
//)
|
||||
}),
|
||||
|
||||
it('unit is a right identity', () => {
|
||||
Monads.forEach(monad => {
|
||||
const m = monad.of(1)
|
||||
|
||||
assert(
|
||||
// NOTE: i heard this one already
|
||||
// @ts-ignore
|
||||
m.chain(monad.of).equals(m)
|
||||
)
|
||||
})
|
||||
}),
|
||||
|
||||
it('unit is associative', () => {
|
||||
Monads.forEach(monad => {
|
||||
const m = monad.of(1)
|
||||
const f = inc(monad)
|
||||
const g = dbl(monad)
|
||||
console.log(m.chain(f))
|
||||
|
||||
// NOTE: it was better the first time
|
||||
// @ts-ignore
|
||||
const x = m.chain(f).chain(g)
|
||||
// @ts-ignore
|
||||
const y = m.chain(x => f(x).chain(g))
|
||||
|
||||
assert(
|
||||
x.equals(y)
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue