多态“翻转”在7.10中失败

时间:2015-04-18 03:58:07

标签: haskell ghc

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应该更严格吗?它似乎不是单形态限制因为一切都有签名。

1 个答案:

答案 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版本之间发生变化时,不要太惊讶。