Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 320
crockeea Avatar asked Oct 20 '22 21:10

crockeea


1 Answers

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.

like image 168
Philip JF Avatar answered Nov 15 '22 10:11

Philip JF