3

Possible Duplicate:
runST and function composition

I've encountered a weird code segment that GHC fails to type-check correctly when composed with id. I'm pretty sure this is a GHC bug, but I wanted to check by here first before filing a bug report with the GHC developers. I'll begin with the working code:

import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV

v :: V.Vector Int
v = V.create $ MV.replicate 1 0

This creates a new vector in the ST monad and works just fine:

>>> v
fromList [0]

The bug occurs when I compose V.create with id:

import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV

v :: V.Vector Int
v = id . V.create $ MV.replicate 1 0

... failing with the following error:

Couldn't match expected type `forall s.
                              GHC.ST.ST s (MV.MVector s a0)'
            with actual type `m0 (MV.MVector
                                    (Control.Monad.Primitive.PrimState m0) a1)'
In the return type of a call of `MV.replicate'
In the second argument of `($)', namely `MV.replicate 1 0'
In the expression: id . V.create $ MV.replicate 1 0

However, if I apply the id instead of composing it, then the code type-checks just fine:

import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV

v :: V.Vector Int
v = id $ V.create $ MV.replicate 1 0

Based on that, I'm guessing that something about composition with id causes GHC to accidentally generalize or specialize V.create, causing it to trigger a type mismatch with MV.replicate. However, beyond that I'm stuck because the type error is a little bit over my head.

It's also not a problem with the monomorphism restriction. The problem persists even when I enable the NoMonomorphismRestriction flag.

This is a pretty weird problem because I would expect id . f == f. Also, the right identity law fails, too, as the following example also fails to type-check:

import qualified Data.Vector as V
import qualified Data.Vector.Mutable as MV

v :: V.Vector Int
v = V.create . id $ MV.replicate 1 0

This is using GHC version 7.4.1 and vector-0.9.1.

Community
  • 1
  • 1
Gabriella Gonzalez
  • 34,863
  • 3
  • 77
  • 135
  • 6
    Strictly, `forall s. ST s something` can't be arguments to `($)` or `(.)`, but there are some special cases because e.g. `runST $ whatever` is so common. However, when composing (`(.)`) or adding another `($)`, these special cases usually don't work anymore. Use parentheses if you don't want to rely on them. – Daniel Fischer Jun 21 '12 at 23:36
  • 2
    Related: http://stackoverflow.com/questions/9468963/runst-and-function-composition – Vitus Jun 21 '12 at 23:41
  • @Vitus That was exactly what I was looking for. It looks like the GHC developers are aware of the issue. It's pretty lame, but at least I know how to work around it. How do I close this and mark it as a duplicate of that one? – Gabriella Gonzalez Jun 21 '12 at 23:52

0 Answers0