Haskell 多个上下文 - 柯里化?

Haskell Multiple Contexts - currying?

在类型签名上写上下文时,通常我会做类似的事情

f :: (Enum a, Ord a) => a -> a

但由于纯粹的运气,我发现它编译并且似乎工作相同,至少在 GHC 7.8 上是这样:

f :: Enum a => Ord a => a -> a

两者在理论上或实践上有何区别?第二个是不是不太正统? Haskell report seems to make no mention of the second form, and I've never seen it used anywhere. Related question.

两个版本是一样的。当约束和 forall-s 不存在时,它们会浮出到范围的顶部。例如,以下定义有效:

foo :: a -> a -> Num a => a
foo = (+)

bar :: a -> forall b. b -> a
bar = const

但是 :t foo 打印 Num a => a -> a -> a:t bar 打印 a -> b -> a(相当于 forall a b. a -> b -> a)。

GHC 不支持多态 return 类型,这就是约束和量词浮动的原因。我想这也可能是 GHC 抛出错误的有效设计选择。