monomorphic库包含以下代码段(希望在7.8中编译):
{-# LANGUAGE DataKinds, ExistentialQuantification, FlexibleContexts, GADTs #-}
{-# LANGUAGE ImpredicativeTypes, PolyKinds, RankNTypes, TypeFamilies #-}
{-# LANGUAGE TypeOperators, UndecidableInstances #-}
class Monomorphicable k where
type MonomorphicRep k :: *
withPolymorphic :: Monomorphicable k
=> MonomorphicRep k -> (forall a. k a -> b) -> b
withPolymorphic k trans = undefined
-- | Flipped version of 'withPolymorphic'.
liftPoly :: Monomorphicable k
=> (forall a. k a -> b) -> MonomorphicRep k -> b
liftPoly = flip withPolymorphic
然而在7.10,GHC抱怨:
Couldn't match type ‘k2 a0 -> b’ with ‘forall (a :: k0). k1 a -> b’
Expected type: MonomorphicRep k2 -> (k2 a0 -> b) -> b
Actual type: MonomorphicRep k1
-> (forall (a :: k0). k1 a -> b) -> b
Relevant bindings include
liftPoly :: (forall (a :: k). k2 a -> b) -> MonomorphicRep k2 -> b
(bound at Data/Type/Monomorphic.hs:45:1)
In the first argument of ‘flip’, namely ‘withPolymorphic’
In the expression: flip withPolymorphic
当然,如果我将liftPoly
的定义更改为
liftPoly a b = withPolymorphic b a
然后7.10很高兴。这里发生了什么?在以某种方式处理多态函数时,7.10应该更严格吗?它似乎不是单形态限制因为一切都有签名。
答案 0 :(得分:10)
flip
的类型是
flip :: (x -> y -> z) -> (y -> x -> z)
要键入check liftPoly
,我们必须在多态类型y
处实例化变量forall a. k a -> b
。这是一个不可预测的多态性的例子。
正如https://ghc.haskell.org/trac/ghc/wiki/ImpredicativePolymorphism上的页面所说,
我们已经做了各种尝试来支持impredicativity,所以有一个标志
-XImpredicativeTypes
。但它不起作用,绝对不受支持。如果你使用它,你就是独立的;我对将要发生的事情没有任何承诺。
所以,当ImpredicativeTypes
的行为在GHC版本之间发生变化时,不要太惊讶。