Haskell 默认值与表达式类型签名的交互
Interaction of Haskell defaulting with expression type signatures
如果我在 Haskell 脚本中键入以下内容:
expressionTypeSigValue = 0 :: Integral a => a
typeSigValue :: Integral a => a
typeSigValue = 0
然后在 GHCi (v. 8.0.2) 中加载它,它告诉我这两个常量有不同的类型:
*Main> :t expressionTypeSigValue
expressionTypeSigValue :: Integer
*Main> :t typeSigValue
typeSigValue :: Integral a => a
我认为 expressionTypeSigValue
的 Integer
类型是类型默认的结果(如果我错了请纠正我)。但我不明白为什么不要求解释器以同样的方式对待这两种类型签名。有人可以解释一下吗?
这是单态限制在起作用。在您的第一个示例中,您指定的是 0
的类型,而不是 expressionTypeSigValue
。无论 0
的类型是 Integral a => a
还是它的自然类型 Num a => a
,单态限制导致它默认为 Integer
。考虑 GHCi 中的以下内容,默认情况下单态限制是关闭的:
-- Without the monomorphism restriction, the polymorphic type of the
-- value is kept.
Prelude> expressionTypeSigValue = 0 :: Integral a => a
Prelude> :t expressionTypeSigValue
expressionTypeSigValue :: Integral a => a
-- With the monomorphism restriction, the polymorphic value
-- is replaced with the default monomorphic value.
Prelude> :set -XMonomorphismRestriction
Prelude> expressionTypeSigValue = 0 :: Integral a => a
Prelude> :t expressionTypeSigValue
expressionTypeSigValue :: Integer
如果我在 Haskell 脚本中键入以下内容:
expressionTypeSigValue = 0 :: Integral a => a
typeSigValue :: Integral a => a
typeSigValue = 0
然后在 GHCi (v. 8.0.2) 中加载它,它告诉我这两个常量有不同的类型:
*Main> :t expressionTypeSigValue
expressionTypeSigValue :: Integer
*Main> :t typeSigValue
typeSigValue :: Integral a => a
我认为 expressionTypeSigValue
的 Integer
类型是类型默认的结果(如果我错了请纠正我)。但我不明白为什么不要求解释器以同样的方式对待这两种类型签名。有人可以解释一下吗?
这是单态限制在起作用。在您的第一个示例中,您指定的是 0
的类型,而不是 expressionTypeSigValue
。无论 0
的类型是 Integral a => a
还是它的自然类型 Num a => a
,单态限制导致它默认为 Integer
。考虑 GHCi 中的以下内容,默认情况下单态限制是关闭的:
-- Without the monomorphism restriction, the polymorphic type of the
-- value is kept.
Prelude> expressionTypeSigValue = 0 :: Integral a => a
Prelude> :t expressionTypeSigValue
expressionTypeSigValue :: Integral a => a
-- With the monomorphism restriction, the polymorphic value
-- is replaced with the default monomorphic value.
Prelude> :set -XMonomorphismRestriction
Prelude> expressionTypeSigValue = 0 :: Integral a => a
Prelude> :t expressionTypeSigValue
expressionTypeSigValue :: Integer