External Publication
Visit Post

Sneak Peek: Bolt Math

Haskell Community [Unofficial] March 22, 2026
Source

ApothecaLabs:

class (Operation r a b) => Lawful r a b where
    lawful :: a -> b -> Bool

I feel (but can not prove) that this will not get you very far. One reason is that not all laws are decidable, because Result r a b might not even have a decent Eq instance that lawful can use. (E.g. point-wise operations on function spaces.) The other case where this fails is when the law involves universal quantification, possibly not only over the elements of a and b but also over type variables. Think about the Monad laws. Of course you can keep adding type parameters to Lawful to cater for all the universal quantification, but the discussion on arity shows that this will be very tricky at best.

Why don’t you do it the categorical way and describe diagrams that ought to commute? For example, the associative law diagram has as starting point a triple and two paths that should be equal. But since equality may not be decidable, we just yield a pair that we require to be “morally equal”.

associative :: Semigroup a => (a,a,a) -> (a,a)
associative (x,y,z) = (x <> (y <> z), (x <> y) <> z)

Whenever Eq a is in scope, you can still post-compose with uncurry (==) and obtain the lawful test.

ApothecaLabs:

Specifically, this class doesn’t assert that it is lawful in general, but rather, that we can check whether a particular operation is lawful.

So you have gained no static guarantees, only more convenient ways to write test suites.

Discussion in the ATmosphere

Loading comments...