import { it, assertEq } from 'folktest'
import { Identity, Constant, Ok, Err, Some, None } from '../../src/index.js'

const leftIdentity = (M, a, f) => {
  assertEq(M(a).bind(f), f(a))
}

const rightIdentity = (M, m) => {
  assertEq(m.bind(M), m)
}

const associativity = (m, f, g) => {
  assertEq(m.bind(f).bind(g), m.bind(x => f(x).bind(g)))
}

export const prove = (M, m, a, f, g) => {
  leftIdentity(M, a, f)
  rightIdentity(M, m)
  associativity(m, f, g)
}

export const Tests = [
  it('should adhere to monadic laws', () => {
    [Identity, Constant, Ok, Err, Some, None].forEach(ctr => {
      prove(
        ctr,
        ctr(1),
        1,
        x => ctr(x + 1),
        x => ctr(x * 2)
      )
    })
  })
]