Первое решение, которое приходит мне в голову, это использование QuickCheck .
quickCheck $ \(x, y, z) -> f x (f y z) == f (f x y) z
quickCheck $ \(x, y) -> f x y == f y x
, где f
- это функция, которую мы тестируем.Это не докажет ни ассоциативность, ни коммутативность;это просто самый простой способ написать решение о грубой силе, о котором вы думали.Преимущество QuickCheck в том, что он позволяет выбирать параметры тестов, которые, будем надеяться, будут угловыми для тестируемого кода.
isAssociative
, который вы запрашиваете, можно определить как
isAssociative
:: (Arbitrary t, Show t, Eq t) => (t -> t -> t) -> IO ()
isAssociative f = quickCheck $ \(x, y, z) -> f x (f y z) == f (f x y) z
Он находится вIO
, поскольку QuickCheck выбирает тестовые наборы случайным образом.