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))) } const rightIdentity = (M, m) => { assert(m.chain(M).equals(m)) } const associativity = (m, f, g) => { assert(m.chain(f).chain(g).equals(m.chain(x => f(x).chain(g)))) } export const prove = (M, m, a, f, g) => { leftIdentity(M, a, f) rightIdentity(M, m) associativity(m, f, g) } const inc = F => x => F.of(x + 1) const dbl = F => x => F.of(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) ) }) }) ]