2016-11-28 84 views
10

我有以下代碼:爲什麼在GHC 7.10中進行類型檢查的代碼不再在GHC 8.0.1中進行類型檢查?

{-# LANGUAGE DefaultSignatures#-} 

import Control.Monad.Trans.Class 
import Control.Monad.Trans.Maybe 

class Monad m => MonadMaybe m where 
    liftMaybe :: Maybe a -> m a 
    default liftMaybe :: (MonadTrans t, MonadMaybe m) => Maybe a -> t m a 
    liftMaybe = lift . liftMaybe 

instance MonadMaybe m => MonadMaybe (MaybeT m) 

使用光榮格拉斯哥Haskell的編譯系統,版本8.0.1.20161117,這無法編譯:

foo.hs:11:10: error: 
    • Couldn't match type ‘m’ with ‘MaybeT m’ 
     ‘m’ is a rigid type variable bound by 
     the instance declaration at foo.hs:11:10 
     Expected type: Maybe a -> MaybeT m a 
     Actual type: Maybe a -> MaybeT (MaybeT m) a 
    • In the expression: Main.$dmliftMaybe @MaybeT m 
     In an equation for ‘liftMaybe’: 
      liftMaybe = Main.$dmliftMaybe @MaybeT m 
     In the instance declaration for ‘MonadMaybe (MaybeT m)’ 
    • Relevant bindings include 
     liftMaybe :: Maybe a -> MaybeT m a (bound at foo.hs:11:10) 

但是在GHC 7.10,這個編譯沒有問題。

GHC 8是否正確,或者我發現了一個錯誤?

+0

出於好奇,如果將默認簽名中的'm'更改爲另一個類型變量,如'n',或者添加一個明確的'forall',它會起作用嗎?我想知道GHC是否因某種原因將m作爲範圍類型變量處理。 –

+1

您的代碼也會在GHC 8.0.1的穩定版本中進行類型檢查。 – duplode

+2

@AlexisKing,基本上就是這個問題。類聲明的頭部(這裏是'm')的出現總是在本體中作用域,否則'm'和方法的類型之間就沒有關係了! –

回答