为什么 `peek` 与多态 Ptr return GHC.Prim.Any 一起使用时与绑定一起使用?
Why does `peek` with a polymorphic Ptr return GHC.Prim.Any when used with a bind?
使用 low-level GNU Science Library bindings Bindings.Gsl.RandomNumberGeneration
,我 运行 进入 GHCi 中的这种奇怪类型行为,其中绑定将 return 类型从 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
λ>
试图明确指定 peek 的类型 return 也无济于事:
λ> x <- (peek p'gsl_rng_mt19937) :: IO (Ptr gsl_rng_type)
λ> :t x
x :: Ptr GHC.Prim.Any
对@user2407038 的评论进行一些扩展:
When you do x <- peek (ptr :: Ptr (Ptr a))
in the GHCi prompt, the type variable a
must be instantiated to some concrete type. This is because the do
notation x <- peek p
means peek p >>= \x -> ...
, where ...
is what you type into GHCi afterwards. Since GHCi can't know the future, it has to "cheat" during typechecking.
回想一下 peek p >>= \x -> ...
中 >>=
的右侧参数,即 lambda 抽象 \x -> ...
、is monomorphic in its argument。这就是 GHCi 必须为 x
分配单态类型的原因。
GHC.Prim.Any
是 GHC 在这种情况下使用的占位符类型,在这种情况下,需要将具体的单态类型分配给没有其他约束的对象。
使用 low-level GNU Science Library bindings Bindings.Gsl.RandomNumberGeneration
,我 运行 进入 GHCi 中的这种奇怪类型行为,其中绑定将 return 类型从 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
λ>
试图明确指定 peek 的类型 return 也无济于事:
λ> x <- (peek p'gsl_rng_mt19937) :: IO (Ptr gsl_rng_type)
λ> :t x
x :: Ptr GHC.Prim.Any
对@user2407038 的评论进行一些扩展:
When you do
x <- peek (ptr :: Ptr (Ptr a))
in the GHCi prompt, the type variablea
must be instantiated to some concrete type. This is because thedo
notationx <- peek p
meanspeek p >>= \x -> ...
, where...
is what you type into GHCi afterwards. Since GHCi can't know the future, it has to "cheat" during typechecking.
回想一下 peek p >>= \x -> ...
中 >>=
的右侧参数,即 lambda 抽象 \x -> ...
、is monomorphic in its argument。这就是 GHCi 必须为 x
分配单态类型的原因。
GHC.Prim.Any
是 GHC 在这种情况下使用的占位符类型,在这种情况下,需要将具体的单态类型分配给没有其他约束的对象。