Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Misunderstanding of SPECIALIZE pragma

The purpose of the SPECIALIZE pragma is to create more specific version of function.

I have a function

adaptBlocks :: Int -> BlocksField a -> Maybe (BlocksField a)

and I specialized it as follows:

{-# SPECIALIZE NOINLINE
    adaptBlocks :: Int -> BlocksField Element -> Maybe (BlocksField Element) #-}

But the compiler gives me this confusing warning:

SPECIALISE pragma for non-overloaded function ‘adaptBlocks’

What's wrong?

like image 237
errfrom Avatar asked Nov 02 '17 15:11

errfrom


1 Answers

Specialization works on bounded polymorphism, where type variables such as a are constrained, e.g.

foo :: (Eq a, Num a) => a -> a -> a
foo x y | x == y    = 2*x
        | otherwise = 3*y 

Here, specializing a ~ Int allows the compiler to inline the Int versions of (==),(*), improving efficiency. Note that such functions are provided by the context (Eq a, Num a).

In your case, there is no context that constrains a, so this optimization can not be performed. After all your polymorphic code can not use (*) or any other numeric function on the Int, since in order to compile, your code must handle any type a, including those which are not numbers.

like image 63
chi Avatar answered Nov 08 '22 21:11

chi