【发布时间】:2016-11-28 17:16:18
【问题描述】:
我有以下代码:
{-# 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)
使用 Glorious Glasgow 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 是否正确,还是我发现了错误?
【问题讨论】:
-
出于好奇,如果将默认签名中的
m更改为另一个类型变量,如n,或者添加显式forall,是否有效?我想知道 GHC 是否出于某种原因在这里将m视为范围类型变量。 -
您的代码还在 GHC 8.0.1 的稳定版本中进行类型检查。
-
@AlexisKing,这基本上就是问题所在。类声明的头部(这里是
m)的出现总是在主体中,否则m和方法的类型之间没有关系! -
@ReidBarton 没错,当然,这是有道理的——回想起来似乎很明显。 :)