10
私は次のコードを持っている:栄光のグラスゴーHaskellのコンパイルシステム、バージョン8.0.1.20161117を使用してなぜ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)
を、これはコンパイルに失敗します。
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は正しいですか、またはバグを発見しましたか?
デフォルトの署名の 'm'を' n'のような別の型変数に変更するか、明示的な 'forall'を追加すると、好奇心をそそられますか?何らかの理由でGHCがスコープ付き変数として 'm'を扱っているのではないかと思います。 –
あなたのコードはGHC 8.0.1の安定版でも型チェックを行います。 – duplode
@AlexisKing、それは本質的に問題です。クラス宣言の頭部(ここでは 'm')の出現は常にボディ内でスコープされます。そうでなければ' m'とメソッドの型の間には関係がありません! –