Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type error when composing any function with the vector `create` function

Tags:

haskell

The following code will be not compile:

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

bad :: V.Vector Int
bad = id . V.create $ do
    v <- MV.new 1
    MV.set v 0
    pure v
• Couldn't match type ‘m0 (MV.MVector
                             (Control.Monad.Primitive.PrimState m0) a0)’
                 with ‘forall s. GHC.ST.ST s (MV.MVector s Int)’
  Expected type: m0 (MV.MVector
                       (Control.Monad.Primitive.PrimState m0) a0)
                 -> V.Vector Int
    Actual type: (forall s. GHC.ST.ST s (MV.MVector s Int))
                 -> V.Vector Int
• In the second argument of ‘(.)’, namely ‘V.create’
  In the expression: id . V.create
  In the expression:
    id . V.create
    $ do { v <- MV.new 1;
           MV.set v 0;
           pure v }

But next will be:

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


good :: V.Vector Int
good = id $ V.create $ do
    v <- MV.new 1
    MV.set v 0
    pure v

stack resolver is lts-9.12

So, why it does and how to fix if I prefer to compose by (.)?

like image 452
freestyle Avatar asked Feb 15 '26 00:02

freestyle


1 Answers

You've hit the fact that GHC can't do impredicative polymorphism. V.create has the higher rank type forall a. Unbox a => (forall s. ST s (MVector s a)) -> Vector a, and when you try to apply it to (id .) :: (x -> y) -> (x -> y) you end up needing to instantiate x = forall s. ST s (MVector s a), which explodes. It's not that there's anything really wrong with the required instantiation; it's just that GHC cannot deal with it. There used to be an extension, ImpredicativePolymorphism, that tried to give limited support, but as of GHC 8 it's completely broken and deprecated. The reason ($) still works is because it's actually hardwired into GHC so that it can avoid the issue, which is why if you tried to define

f $$ x = f x

and used it instead of ($) here it'd fail similarly to (id .).

like image 112
HTNW Avatar answered Feb 16 '26 19:02

HTNW



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!