1
0
mirror of https://github.com/IBM/fp-go.git synced 2025-06-23 00:27:49 +02:00
Files
fp-go/internal/chain/testing/laws.go

85 lines
2.0 KiB
Go
Raw Normal View History

package testing
import (
"testing"
E "github.com/ibm/fp-go/eq"
F "github.com/ibm/fp-go/function"
L "github.com/ibm/fp-go/internal/apply/testing"
"github.com/stretchr/testify/assert"
)
// Chain associativity law
//
// F.chain(F.chain(fa, afb), bfc) <-> F.chain(fa, a => F.chain(afb(a), bfc))
func AssertAssociativity[HKTA, HKTB, HKTC, A, B, C any](t *testing.T,
eq E.Eq[HKTC],
fofa func(A) HKTA,
fofb func(B) HKTB,
fofc func(C) HKTC,
chainab func(HKTA, func(A) HKTB) HKTB,
chainac func(HKTA, func(A) HKTC) HKTC,
chainbc func(HKTB, func(B) HKTC) HKTC,
ab func(A) B,
bc func(B) C,
) func(fa HKTA) bool {
return func(fa HKTA) bool {
afb := F.Flow2(ab, fofb)
bfc := F.Flow2(bc, fofc)
left := chainbc(chainab(fa, afb), bfc)
right := chainac(fa, func(a A) HKTC {
return chainbc(afb(a), bfc)
})
return assert.True(t, eq.Equals(left, right), "Chain associativity")
}
}
// AssertLaws asserts the apply laws `identity`, `composition`, `associative composition` and `associativity`
func AssertLaws[HKTA, HKTB, HKTC, HKTAB, HKTBC, HKTAC, HKTABAC, A, B, C any](t *testing.T,
eqa E.Eq[HKTA],
eqc E.Eq[HKTC],
fofa func(A) HKTA,
fofb func(B) HKTB,
fofc func(C) HKTC,
fofab func(func(A) B) HKTAB,
fofbc func(func(B) C) HKTBC,
faa func(HKTA, func(A) A) HKTA,
fab func(HKTA, func(A) B) HKTB,
fac func(HKTA, func(A) C) HKTC,
fbc func(HKTB, func(B) C) HKTC,
fmap func(HKTBC, func(func(B) C) func(func(A) B) func(A) C) HKTABAC,
chainab func(HKTA, func(A) HKTB) HKTB,
chainac func(HKTA, func(A) HKTC) HKTC,
chainbc func(HKTB, func(B) HKTC) HKTC,
fapab func(HKTAB, HKTA) HKTB,
fapbc func(HKTBC, HKTB) HKTC,
fapac func(HKTAC, HKTA) HKTC,
fapabac func(HKTABAC, HKTAB) HKTAC,
ab func(A) B,
bc func(B) C,
) func(fa HKTA) bool {
// apply laws
apply := L.AssertLaws(t, eqa, eqc, fofab, fofbc, faa, fab, fac, fbc, fmap, fapab, fapbc, fapac, fapabac, ab, bc)
// chain laws
associativity := AssertAssociativity(t, eqc, fofa, fofb, fofc, chainab, chainac, chainbc, ab, bc)
return func(fa HKTA) bool {
return apply(fa) && associativity(fa)
}
}