Haskell:使用sizeOf时Storable中的模糊类型变量

时间:2014-04-13 18:21:50

标签: 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 -> 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_list_to_storable必须始终被称为byte_list_to_storable undefined ...。有没有办法在没有伪论证的情况下解决歧义?

1 个答案:

答案 0 :(得分:8)

Haskell类型变量,例如a,默认情况下只存在于一个特定类型的签名中。当你进一步向下写sizeOf (undefined :: a)时,在函数定义中,GHC不会以任何方式将此aMaybeT IO a中的ScopedTypeVariables相关联,而是将其解释为全新的,不受约束的,类型变量。

更改此方法的方法是启用{-# LANGUAGE ScopedTypeVariables #-} byteListToStorable :: forall a . Storable a => [CUChar] -> MaybeT IO a byteListToStorable bytelist = do let sizeOfStorable = sizeOf (undefined :: a) ...

{{1}}