Haskell:使用 sizeOf 时 Storable 中的不明确类型变量



编译

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 ...。有没有办法在没有虚拟论证的情况下解决歧义?

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)
     ...

最新更新