Search code examples
haskellgadtderivinginfix-operator

Can I make haskell GADT data constructor infix in derived Show?


Consider two data declarations:

{-# LANGUAGE GADTs #-}

data X = Int `Y` Int deriving Show

data Z where
        W :: Int -> Int -> Z  deriving Show

main = do
         print (1 `Y` 2)
         print (3 `W` 4)

Running the above program produces:

1 `Y` 2
W 3 4

so the derived show knows that Y is infix and prints it accordingly. The :: syntax doesn't seem to allow infixness.

Is there any way to make the compiler derive show for W as infix, (other than explicitly providing a show instance for Z)? The desired output is

1 `Y` 2
3 `W` 4

Solution

  • Not currently. GADT constructors are only flagged as infix under a specific set of conditions:

    Note [Infix GADT constructors]
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    We do not currently have syntax to declare an infix constructor in GADT syntax,
    but it makes a (small) difference to the Show instance.  So as a slightly
    ad-hoc solution, we regard a GADT data constructor as infix if
      a) it is an operator symbol
      b) it has two arguments
      c) there is a fixity declaration for it
    For example:
       infix 6 (:--:)
       data T a where
         (:--:) :: t1 -> t2 -> T Int
    

    So for a non-symbolic constructor like W, it looks like you're out of luck, but if you're willing to make it symbolic, you can just add a fixity declaration.

    (hat tip to this template haskell bug thread)