为什么Haskell会推断一个特定类型(显然)不一致?

7 haskell type-inference

我正在编写一个玩具(物理)矢量库,并且我遇到GHC问题,坚持功能应该Integer在他们的类型中.我想要向量乘以向量,以及标量(只是使用*),虽然这可能只是有Vector实例Num我现在得到排序的错误:

Couldn't match expected type `Integer' with actual type `Double'
Run Code Online (Sandbox Code Playgroud)

在使用代码来解决这个问题之后我已经把它归结为:

data V a = V a a a deriving (Show, Eq, Functor)
scale a (V i j k) = V (a*i) (a*j) (a*k)
(<.>) = scale
Run Code Online (Sandbox Code Playgroud)

现在,如果我们问GHCi我们得到的是什么类型:

>:t scale
scale :: Num a => a -> V a -> V a
>:t (<.>)
(<.>) :: Integer -> V Integer -> V Integer
Run Code Online (Sandbox Code Playgroud)

我们当然不希望<.>只对Integers 采取行动.虽然这可以通过包含类型签名来解决<.>,但我想知道实际发生了什么.

rkh*_*rov 15

你正在遇到臭名昭着的单态限制.另一种解决方案是明确指定参数:

a <.> v = scale a v
Run Code Online (Sandbox Code Playgroud)

或者添加-XNoMonomorphismRestrictionpragma.

  • ...或添加类型签名.无论如何,所有顶级函数上的类型签名都被认为是好的样式,因此这是我避免单态约束相关问题的首选方法. (15认同)