Search code examples
haskellghcpragma

Forall'd constraint is not bound in RULE by lhs


I'm messing around with the SPECIALIZE pragma while trying to find a solution to this problem.

I came up with this example:

{-# LANGUAGE FlexibleContexts, GeneralizedNewtypeDeriving #-}

import Data.Vector
import qualified Data.Vector.Generic as V

class Foo a

newtype Phantom m = T Int deriving (Show)

instance (Foo m) => Num (Phantom m)

f :: (Num r, V.Vector v r) => v r -> v r -> v r
{-# SPECIALIZE f :: (Foo m) => Vector (Phantom m) -> Vector (Phantom m) -> Vector (Phantom m) #-}
f x y = V.zipWith (+) x y

main = print "hello"

which fails to compile (GHC 7.6.2) because

Forall'd constraint `Foo m' is not bound in RULE lhs.

Googling only turned up a couple of GHC bug reports from years ago. I didn't see anything about "forall'd constraints" while reading about SPECIALIZE or RULE. My specialize signature does seem less polymorphic than the original, and it satisfies the "if-and-only-if" rule.


Solution

  • replace with

    {-# SPECIALIZE f :: (Num (Phantom m)) => Vector (Phantom m) -> Vector (Phantom m) -> Vector (Phantom m) #-}
    

    and it will work. The r in Num r is Phantom m not m, thus you can't add the constraint Num m. This is logical--Num (Phantom m) does not imply Num m and you could get other instances under the open world assumption.

    EDIT: You actually don't need any constraint at all in this case

    {-# SPECIALIZE f :: Vector (Phantom m) -> Vector (Phantom m) -> Vector (Phantom m) #-}
    

    anyway, the basic problem if I understand what you are trying to do is that you can't constrain when you perform an optimization based on phantom type parameters.