Haskell:使用sizeOf时可存储中的类型变量不明确
汇编Haskell:使用sizeOf时可存储中的类型变量不明确,haskell,Haskell,汇编 byte_list_to_storable :: Storable a => [CUChar] -> MaybeT IO a byte_list_to_storable byte_list = do let size_of_storable = sizeOf (undefined :: a) when (length byte_list /= size_of_storable) mzero liftIO . alloca $ \pointer
byte_list_to_storable :: Storable a => [CUChar] -> MaybeT IO a
byte_list_to_storable byte_list = do
let
size_of_storable = sizeOf (undefined :: a)
when (length byte_list /= size_of_storable) mzero
liftIO . alloca $ \pointer -> do
forM (zip [0 .. size_of_storable - 1] byte_list)
(\(index, byte) -> pokeByteOff pointer index byte)
peek pointer
失败于
Ambiguous type variable `a0' in the constraint:
(Storable a0) arising from a use of `sizeOf'
Probable fix: add a type signature that fixes these type variable(s)
In the expression: sizeOf (undefined :: a)
In an equation for `size_of_storable':
size_of_storable = sizeOf (undefined :: a)
In the expression:
do { let size_of_storable = sizeOf (undefined :: a);
when (length byte_list /= size_of_storable) mzero;
liftIO . alloca $ \ pointer -> do { ... } }
尽管有显式类型注释。可以使用伪参数修复它:
byte_list_to_storable :: Storable a => a -> [CUChar] -> MaybeT IO a
byte_list_to_storable dummy byte_list = do
let
size_of_storable = sizeOf dummy
但是
byte\u list\u to\u storable
必须始终被称为byte\u list\u to\u storable undefined…
。有没有办法在没有伪参数的情况下解决歧义?Haskell类型变量,如a
,默认情况下仅在一个特定类型签名中有效。在函数定义中进一步写入sizeOf(undefined::a)
时,GHC不会以任何方式将此a
与MaybeT IO a
中的变量相关联,而是将其解释为一个全新的、无约束的类型变量
改变这种情况的方法是打开ScopedTypeVariables
:
{-# LANGUAGE ScopedTypeVariables #-}
byteListToStorable :: forall a . Storable a => [CUChar] -> MaybeT IO a
byteListToStorable bytelist = do
let sizeOfStorable = sizeOf (undefined :: a)
...
Haskell类型变量,如
a
,默认情况下只存在于一个特定的类型签名中。在函数定义中进一步写入sizeOf(undefined::a)
时,GHC不会以任何方式将此a
与MaybeT IO a
中的变量相关联,而是将其解释为一个全新的、无约束的类型变量
改变这种情况的方法是打开ScopedTypeVariables
:
{-# LANGUAGE ScopedTypeVariables #-}
byteListToStorable :: forall a . Storable a => [CUChar] -> MaybeT IO a
byteListToStorable bytelist = do
let sizeOfStorable = sizeOf (undefined :: a)
...
你想在这里干什么?你希望从哪里推断出
a
的类型呢?@code Guru我正在从字节列表中构造一个可存储的值。列表应该有正确的长度,这就是为什么我需要使用sizeOf
获得我正在构建的值类型的大小。a
的类型在调用byte\u list\u to\u storable
时指定,例如value::FunPtr(IO())是未定义的部分,它只是存根尚未完成的内容?@code Guru否,它不是存根。我们必须给sizeOf
一个值,即使它不以任何方式检查它。所以,当我们没有任何值时,我们使用未定义的?你希望从哪里推断出a
的类型呢?@code Guru我正在从字节列表中构造一个可存储的值。列表应该有正确的长度,这就是为什么我需要使用sizeOf
获得我正在构建的值类型的大小。a
的类型在调用byte\u list\u to\u storable
时指定,例如value::FunPtr(IO())是未定义的部分,它只是存根尚未完成的内容?@code Guru否,它不是存根。我们必须给sizeOf
一个值,即使它不以任何方式检查它。所以,当我们没有任何值时,我们使用未定义的
。现在它可以工作了,谢谢!实际上,我启用了ScopedTypeVariables
,所以答案似乎只是为所有a添加。
。您说过,默认情况下,任何签名中的类型变量只引用该特定签名,因此为所有a添加。
会使函数的类型签名中的类型变量也引用其定义。这就是它的工作原理吗?@myrix是的,没错。扩展只允许为所有a b c。。。对于要在函数体上确定作用域的每个类型变量。感谢@Sarah!的确认!现在它工作了,谢谢!实际上,我启用了ScopedTypeVariables
,所以答案似乎只是为所有a添加。
。您说过,默认情况下,任何签名中的类型变量只引用该特定签名,因此为所有a添加。
会使函数的类型签名中的类型变量也引用其定义。这就是它的工作原理吗?@myrix是的,没错。扩展只允许为所有a b c。。。对于要在函数体上确定作用域的每个类型变量。感谢@Sarah!的确认!