为什么在Haskell中不允许这个声明?

bse*_*old 5 haskell

我知道FunctorApplicative应该是超Monad,但不是由于历史的原因.但是,为什么不能声明Monad一个实例Functor呢?这将产生大致相同的效果,但无需修改现有代码.如果你想这样做,GHC抱怨:

instance Functor Monad where
   fmap = liftM

Class `Monad' used as a type
In the instance declaration for `Functor Monad'
Run Code Online (Sandbox Code Playgroud)

这是为什么?这可能是一个很好的理由.

fuz*_*fuz 11

你的语法错了.Monad是类型类,而不是数据类型.你能写的是什么

instance Monad a => Functor a where fmap = liftM
Run Code Online (Sandbox Code Playgroud)

然而,这只会与扩展工作FlexibleInstances(许可情况下是形式的不哪里是类型变量并没有上下文)和(允许这个特定的实例[我不知道这是为什么需要]).T a1 a2 ... ana1, a2, ... anUndecidableInstances

  • dave4420是不正确的:冲突的声明会暗示`OverlappingInstances`或`IncoherentInstances`.这需要`UndecidableInstances`的原因如下:当检查`Foo`是否是一个'Functor`时,这个规则意味着我们必须检查`Foo`是一个'Monad` - 也就是说,我们必须递归到实例查找算法的类型_ not_小于我们开始的类型.如果我们允许这样的递归,那么编写永远不会停止递归的实例很容易,而如果类型必须在每一步都变小,那么显然是不可能的. (6认同)
  • 需要"UndecidableInstances",因为声明与明确定义为仿函数的每个monad冲突,包括标准库中的所有monad. (3认同)