-- |
-- Module      : Math
-- License     : BSD-3-Clause
-- Copyright   : (c) 2025 Olivier Chéron
--
-- Type classes that define additive and multiplicative operations, as well as
-- a multiply-then-add operation that will often optimize chaining.
--
-- The module also defines a non-homogenous multiplication that combines
-- typically a public operand (left) with a secret operand (right), producing a
-- secret output.
--
{-# LANGUAGE MultiParamTypeClasses #-}
module Math
    ( Add(..), Mul(..), MulAdd(..), BiMul(..), BiMulAdd(..)
    ) where

infixl 7 .*
infixr 7 ..*
infixl 6 .+, .-

class Add a where
    zero :: a
    (.+) :: a -> a -> a
    (.-) :: a -> a -> a
    neg :: a -> a

class Add a => Mul a where
    one :: a
    (.*) :: a -> a -> a

class Mul a => MulAdd a where
    -- invariant: mulAdd a b c == a .* b .+ c
    mulAdd :: a -> a -> a -> a

class Add a => BiMul b a where
    (..*) :: b -> a -> a

class BiMul b a => BiMulAdd b a where
    -- invariant: biMulAdd a b c == a ..* b .+ c
    biMulAdd :: b -> a -> a -> a