I've done a Haskell library allowing to manipulate multivariate polynomials. It uses some instances defined by the numeric-prelude library, e.g. an additive group instance. The addition for this instance is denoted in this library. I find this a bit annoying because there's already the usual for numbers, so I defined:
import Algebra.Additive as AlgAdd
(^ ^) :: Polynomial a -> Polynomial a -> Polynomial a
(^ ^) p q = p AlgAdd. q
But it seems to me that by doing that, the "infix properties" of are lost. I never dealt with the infix properties, and I have a couple of questions. I want to keep the same infix properties.
Looking at the code I see this line:
infixl 6 , -
This line is isolated, at the beginning of the code. So should I similarly include the line
infixl 6 ^ ^, ^-^
at the beginning of my code? In this blog post the author defines the infix property of a function just before defining this function. Is it another, equivalent way to proceed? And is it not possible to do something like (^ ^) = (AlgAdd. ) in such a way that the infix properties are automatically copied?
Still looking at the code, I see:
{-# MINIMAL zero, ( ), ((-) | negate) #-}
What does that mean?
I'm also wondering how to define the opposite of a polynomial. I have the substraction
p ^-^ qbut how to define^-^ p?Finally, when the package author defines the instance e.g. for
Double, he/she writes:instance C Double where {-# INLINE zero #-} {-# INLINE negate #-} {-# INLINE ( ) #-} {-# INLINE (-) #-} zero = P.fromInteger 0 negate = P.negate ( ) = (P. ) (-) = (P.-)
What is the purpose of INLINE?
CodePudding user response:
You can write the infix declaration above the definition, but it's not a requirement.
infixl 6 ^ ^, ^-^ (^ ^) :: Polynomial a -> Polynomial a -> Polynomial a (^ ^) = (AlgAdd. )The infix properties cannot be copied.
The
Minimalpragma refers to the "minimal set of methods that must be defined" for a class definition to be total. In your case it means you can either write a definition for the methods "zeroand( )and(-)" or "zeroand( )andnegate" since you can definenegatein terms of the first groupnegate a = zero - aand
(-)in terms of the second. So it doesn't matter which one you define.n - m = n negate mNot sure.
The
Inlinepragma forces ghc to inline (unfold) the definition. Here is the answer to Is there ever a reason to not mark a monadic bind operator(>>=)as inline?
CodePudding user response:
Without a fixity declaration, your operators ^ ^ and ^-^ will behave as if declared with
infixl 9 ^ ^, ^-^
that is, left-associative with extremely high precedence. If you want them to behave more or less like "regular" addition and subtraction, then you should explicitly declare them to have precedence level 6 with
infixl 6 ^ ^, ^-^
The associativity and precedence levels are not "transferable" from another operator; you'll just have to look up the behavior of the operator you want to be similar to and declare yours appropriately.
