ScopedTypeVariables不会将类型变量引入作用域

7
这里有一个简单的函数,可用于返回指针的对齐方式:
{-# LANGUAGE ScopedTypeVariables #-}

import Foreign.Ptr (Ptr)
import Foreign.Storable (Storable, alignment)

main = return ()

ptrAlign1 :: (Storable a) => Ptr a -> Int
ptrAlign1 _ = alignment (undefined :: a) 

但是我收到了以下错误:

Could not deduce (Storable a0) arising from a use of `alignment'
from the context (Storable a)
  bound by the type signature for
             ptrAlign1 :: Storable a => Ptr a -> Int
  at prog.hs:8:14-41
The type variable `a0' is ambiguous

如果我以以下更凌乱的方式重新编写ptrAlign

ptrAlign2 :: (Storable a) => Ptr a -> Int
ptrAlign2 = ptrAlign3 undefined where
  ptrAlign3 :: (Storable a) => a -> Ptr a -> Int
  ptrAlign3 x _ = alignment x

它运行良好(当然,这个版本甚至不需要ScopedTypeVariables)。

但我仍然很好奇为什么第一个版本会抛出错误,以及应该如何解决?

1个回答

10

即使打开了ScopedTypeVariables,类型变量也不会被放入作用域,除非你明确地量化它们,例如

ptrAlign1 :: forall a. (Storable a) => Ptr a -> Int
ptrAlign1 _ = alignment (undefined :: a) 

1
这背后的原理是什么? - Erik Kaplun
@ErikAllik: 该手册没有明确说明,但我认为这是为了防止现有代码仅通过打开“ScopedTypeVariables”而改变其行为。 - Antal Spector-Zabusky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接