
Here is an apparent bug in ghc's specialisation rules. The rewrite rule generated by a SPECIALISE pragma seems to want to pattern-match on exact dictionaries (as well as types). But the compiler is not necessarily able to fully resolve dictionaries before the rules are supposed to fire. First, the source code we want to specialise: {-# SPECIALISE hedgehog :: Float -> Vector3 Float -> [Cell_8 (Coord3 Float)] -> [Cell_8 (Vector3 Float)] -> [(Coord3 Float, Coord3 Float)] #-} hedgehog :: ( Fractional a, Cell cell vert, Eq vert , Geom coord, Geom vector, Embed vector coord ) => a -> vector a -> [cell (coord a)] -> [cell (vector a)] -> [(coord a, coord a)] And the core + interface generated for this module contains the rule: "SPEC Hedgehog.hedgehog" ALWAYS forall Hedgehog.hedgehog @ GHC.Float.Float @ RectGrid.Cell_8 @ CellTypes.MyVertex @ Geometries.Coord3 @ Graphics.Rendering.OpenGL.GL.CoordTrans.Vector3 GHC.Float.$f16 RectGrid.$f2 CellTypes.$f1 Geometries.$f5 Geometries.$f3 Geometries.$f1 = Hedgehog.hedgehog1 But in a different module, here is what the usage site looks like just before the specialisation rules are supposed to fire: hedgehog_a4wy = Hedgehog.hedgehog @ GHC.Float.Float @ RectGrid.Cell_8 @ CellTypes.MyVertex @ Geometries.Coord3 @ Graphics.Rendering.OpenGL.GL.CoordTrans.Vector3 $dFractional_a4xP RectGrid.$f2 CellTypes.$f1 (Dataset.$p2Embed @ Graphics.Rendering.OpenGL.GL.CoordTrans.Vector3 @ Geometries.Coord3 Geometries.$f1) (Dataset.$p1Embed @ Graphics.Rendering.OpenGL.GL.CoordTrans.Vector3 @ Geometries.Coord3 Geometries.$f1) Geometries.$f1 Notice how there are several dictionary selector functions sitting there, so although some of the dictionaries match, not all do, and the rule does not fire. However, later the worker-wrapper transformation is able to resolve those outstanding dictionaries, giving: hedgehog_a4wy = Hedgehog.$whedgehog @ GHC.Float.Float @ RectGrid.Cell_8 @ CellTypes.MyVertex @ Geometries.Coord3 @ Graphics.Rendering.OpenGL.GL.CoordTrans.Vector3 GHC.Float.$f16 RectGrid.$f2 Geometries.$f5 Geometries.$f3 Geometries.$f1 So I'm left calling the worker for the polymorphic version of the function, rather than the specialised monomorphic code I wanted. Given how many dictionaries are involved, and that this is the inner loop of the program, I'm hoping there is a big performance win waiting for me, if only I can get that specialised code to run! Regards, Malcolm