Why does `peek` with polymorphic Ptr return GHC.Prim.Any when used with linking?
Using low-level bindings to the GNU Science libraryBindings.Gsl.RandomNumberGeneration
, I came across this odd type of behavior in GHCi where bind changes to bindings from type peek
to GHC.Prim.Any
. I am trying to figure out why, as I cannot use c'rng_alloc
if not save the type of the pointer to rng
. For example:
λ> :t c'gsl_rng_alloc
c'gsl_rng_alloc :: Ptr C'gsl_rng_type -> IO (Ptr C'gsl_rng)
λ> :t p'gsl_rng_mt19937
p'gsl_rng_mt19937 :: Ptr (Ptr gsl_rng_type)
λ> :t peek p'gsl_rng_mt19937
peek p'gsl_rng_mt19937 :: IO (Ptr gsl_rng_type)
λ> x <- peek p'gsl_rng_mt19937
λ> :t x
x :: Ptr GHC.Prim.Any
λ> c'gsl_rng_alloc x
<interactive>:421:17:
Couldn't match type ‘GHC.Prim.Any’ with ‘C'gsl_rng_type’
Expected type: Ptr C'gsl_rng_type
Actual type: Ptr GHC.Prim.Any
In the first argument of ‘c'gsl_rng_alloc’, namely ‘x’
In the expression: c'gsl_rng_alloc x
λ>
Trying to explicitly specify the return type of peek, which doesn't help:
λ> x <- (peek p'gsl_rng_mt19937) :: IO (Ptr gsl_rng_type)
λ> :t x
x :: Ptr GHC.Prim.Any
source to share
To expand a bit on @ user2407038's comment:
When you run
x <- peek (ptr :: Ptr (Ptr a))
at a GHCi prompt, a type variablea
must be created for a specific type. This is because the notationdo
x <- peek p
meanspeek p >>= \x -> ...
where...
is what you enter subsequently into GHCi. Since GHCi cannot know the future, it must "cheat" during type checking.
Recall that the peek p >>= \x -> ...
right-hand argument >>=
, namely the lambda abstraction \x -> ...
, is monomorphic in its argument . This is why GHCi must assign a monomorphic type x
.
GHC.Prim.Any
- the type of placeholder that GHC uses in situations where a particular monomorphic type must be bound to something that has no other restrictions.
source to share