为什么`peek`与多态Ptr返回GHC.Prim.Any与绑定一起使用?

时间:2015-05-04 17:18:12

标签: pointers haskell ghc ghci parametric-polymorphism

使用low-level GNU Science Library bindings Bindings.Gsl.RandomNumberGeneration,我在GHCi中遇到这种奇怪的行为,其中绑定更改将类型从peek返回到GHC.Prim.Any。我试图理解为什么我不能使用c'rng_alloc,除非我保留指向rng的指针类型。例如:

λ> :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
λ> 

尝试明确指出不会有帮助的偷看回复的类型:

λ> x <- (peek p'gsl_rng_mt19937) :: IO (Ptr gsl_rng_type)
λ> :t x
x :: Ptr GHC.Prim.Any

1 个答案:

答案 0 :(得分:3)

稍微扩展一下@ user2407038的评论:

  

当您在GHCi提示符中执行x <- peek (ptr :: Ptr (Ptr a))时,必须将类型变量a实例化为某种具体类型。这是因为do符号x <- peek p表示peek p >>= \x -> ...,其中...是您之后输入GHCi的内容。由于GHCi无法知道未来,它必须在类型检查中“作弊”。

回想一下peek p >>= \x -> ...>>=的右手参数,即lambda抽象\x -> ...is monomorphic in its argument。这就是GHCi必须为x指定单态类型的原因。

GHC.Prim.Any是GHC在这种情况下使用的占位符类型,其中需要将具体的单态类型分配给没有其他约束的东西。