Pointers 为什么带有多态Ptr的'peek'与bind一起使用时返回GHC.Prim.Any?

Pointers 为什么带有多态Ptr的'peek'与bind一起使用时返回GHC.Prim.Any?,pointers,haskell,ghc,ghci,parametric-polymorphism,Pointers,Haskell,Ghc,Ghci,Parametric Polymorphism,使用,我在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_

使用,我在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
λ> 
λ>: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_类型)
λ> :t peek p'gsl_rng_mt19937
peek p'gsl_rng_mt19937::IO(Ptr gsl_rng_类型)

λ> 要对@user2407038的评论进行一些扩展:

当您执行
x=\x->…
,其中
是您随后在GHCi中键入的内容。由于GHCi不知道未来,它必须在打字检查时“作弊”

回想一下,在
peek p>=\x->…
中,
>=
的右参数,即lambda抽象
\x->…
。这就是为什么GHCi必须将单态类型分配给
x


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

请注意,
gsl\u rng\u type
这里只是一个类型变量,因此
p'gsl\u rng\u mt19937
具有类型
Ptr(Ptr a)
您的尝试与说
x@hammar我明白了,我把类型变量
gsl\u rng
\u type和类型
C'gsl\u rng
搞混了。我是haskell的新手,不熟悉绑定dsl如何生成FFI代码。如何将gsl_rng_type的值传递给alloc函数。在C语言中,它看起来像是
gsl\u rng*rng=gsl\u rng\u alloc(gsl\u rng\u mt19937)
。我猜您需要投射指针。看看函数。你能添加一个答案吗?当你做
x=\x->…
,其中
是你在ghci中键入的内容。由于ghci不知道未来,它必须在打字检查时“作弊”。
λ> x <- (peek p'gsl_rng_mt19937) :: IO (Ptr gsl_rng_type)
λ> :t x
x :: Ptr GHC.Prim.Any