Home > Net >  infix properties of operators in Haskell
infix properties of operators in Haskell

Time:07-30

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.

  1. 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?

  1. Still looking at the code, I see:

    {-# MINIMAL zero, ( ), ((-) | negate) #-}
    

What does that mean?

  1. I'm also wondering how to define the opposite of a polynomial. I have the substraction p ^-^ q but how to define ^-^ p?

  2. 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:

  1. 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.

  2. The Minimal pragma 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 "zero and ( ) and (-)" or "zero and ( ) and negate" since you can define negate in terms of the first group

    negate a = zero - a
    

    and (-) in terms of the second. So it doesn't matter which one you define.

    n - m = n   negate m
    
  3. Not sure.

  4. The Inline pragma 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.

  • Related